0

初めての投稿なのであまり間違えないように…

次の問題に直面しています。このコードを実行すると (かなり長くなって申し訳ありません)、LAPACKE 呼び出し中に「解決」関数でセグメンテーション違反が発生しました。

問題は、メイン関数でファイル「dataf」を開こうとしない場合です。このコードは、(目に見える) 問題なく実行されます。

タイプのボブとポインターを台無しにしたと思いますが、あなたの視点を持ちたいと思います。

よろしくお願いします

ティボー

#include <stdio.h>
#include <stdlib.h>
#include <lapacke/lapacke.h>

typedef struct{
   double *data;
   double *tmp;
   double **A;
   int size;
 } Bob;

void allocate(Bob *b);
void init_data(Bob *b);
void init_A(Bob* b);

void allocate(Bob *b){
   b->data = malloc(b->size*sizeof(double));
   b->tmp = malloc(b->size*sizeof(double));
   b->A = malloc(4*sizeof(double*));
   b->A[0] = malloc(b->size*sizeof(double));
   b->A[1] = malloc(b->size*sizeof(double));
   b->A[2] = malloc(b->size*sizeof(double));
   b->A[3] = malloc(b->size*sizeof(double));
}

void init_data(Bob *b){
   int i;
   for (i=0;i<b->size;i++){
      b->data[i] = 0.0;
   }
}

void init_A(Bob* b){
   int i;
   double *diag = b->A[0];
   double *down = b->A[1];
   double *up = b->A[2];
   double *up2 = b->A[3];

   for (i=0;i<b->size;i++){
     diag[i] = 2.0;
     down[i] = -1.0;
     up[i] = -1.0;
     up2[i] = 0.0;
   }
}

void solve(Bob *b){
   lapack_int info;
   lapack_int *ipiv = malloc(b->size*(sizeof(lapack_int)));
   lapack_int lsize = b->size;
   lapack_int lone = 1;

   int i;
   for (i=0;i<b->size;i++){
      b->tmp[i] = b->data[i];
   }

   info = LAPACKE_dgttrs(LAPACK_COL_MAJOR,'N',
     lsize,lone,\
     b->A[1],b->A[0],b->A[2],b->A[3],\
     ipiv, b->tmp, lsize);

   printf("%d\n",info);
   free(ipiv);
 }

int main(void){
   Bob b;
   b.size = 10000;
   allocate(&b);
   init_A(&b);
   init_data(&b);
// No Segfault if dataf is not opened
   FILE *dataf;
   dataf = fopen("data","w");
   fclose(dataf);
   solve(&b);

   free(b.data);
   free(b.tmp);
   free(b.A[0]);
   free(b.A[1]);
   free(b.A[2]);
   free(b.A[3]);
   free(b.A);
   return 0;
}

Makefile を使用:

P=mini
CC=gcc

CFLAGS=-g -Wall
LFLAGS=-lm -llapacke -llapack -lblas

FILES=min.c

all: $(FILES)
   $(CC) $(CFLAGS) $(LFLAGS) $(FILES) -o $(P)

編集:元の投稿で間違いを犯しました。A[0] -> A[3] の割り当ては double であり、double へのポインターではありません。

解決後に fclose の位置を変更すると、問題が解決するようです。しかし、私の実際のコードでは何も変わりません...

EDIT2: 問題は LAPACK 関数に関連しているようです。私はこの関数を (私の問題により適したものに) 変更し、メモリの問題はなくなりました。

元の問題の解決策ではありませんが、特定の方法で解決しました。とにかく非常に役立つすべての返信とコメントをありがとう:)

EDIT3: 問題の原因を見つけました。LAPACK関連です。関数解決では、ipiv 用のスペースを割り当てています。ただし、LAPACKE_dgttrs は、init_A の関数 LAPACKE_dgttrf によって与えられる ipiv を入力として受け取ります。

そのため、構造体に ipiv のポインターを割り当て、それをプログラムの残りの部分で使用します。

4

2 に答える 2

0

「Bob」の定義では、メンバー A はポインターへのポインターとして定義されており、コードに基づいて、double の 2 次元配列を設定していると想定しています。その場合、a b->A[i] を割り当てる 4 つのステートメントは、double へのポインターではなく、double を割り当てる必要があります。

void allocate(Bob *b){
   b->data = malloc(b->size*sizeof(double));
   b->tmp = malloc(b->size*sizeof(double));
   b->A = malloc(4*sizeof(double*));
   b->A[0] = malloc(b->size*sizeof(double));
   b->A[1] = malloc(b->size*sizeof(double));
   b->A[2] = malloc(b->size*sizeof(double));
   b->A[3] = malloc(b->size*sizeof(double));
}
于 2014-07-30T11:40:14.720 に答える
0

エラーは fclose 関数によるものです。fclose の前に、dataf が NULL または noy かどうかを確認してください。

FILE *dataf;
dataf = fopen("data","w"); //If file is not opened for writing, the dataf is NULL
fclose(dataf);   
solve(&b);

への変更

FILE *dataf;
dataf = fopen("data","w");

if(dataf != NULL)
    fclose(dataf);
solve(&b);
于 2014-07-30T11:28:36.750 に答える