0

由于这是我第一次在这里发帖,我希望我不会犯太多错误......

我面临以下问题。当我运行这段代码时(很抱歉,我很抱歉)在 LAPACKE 调用期间,我在“解决”函数中遇到了分段错误。

问题是当我不尝试在主函数中打开文件“dataf”时,此代码运行时没有任何(可见)问题。

我想我搞砸了我的类型 Bob 和指针,但我想听听你的观点。

此致

蒂博

#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] 的分配是双精度数,而不是指向双精度数的指针。

解决后更改 fclose 的位置似乎可以解决问题。但在我的真实代码中它不会改变任何东西......

EDIT2:问题似乎与 LAPACK 功能有关。我改变了这个功能(更适合我的问题)并且内存问题现在已经消失了。

这不是我原来问题的解决方案,但我以某种方式解决了它。感谢所有非常有用的回复和评论:)

EDIT3:我找到了问题的根源。它与LAPACK有关。在函数求解中,我为 ipiv 分配空间。但是 LAPACKE_dgttrs 将 init_A 中的函数 LAPACKE_dgttrf 给出的 ipiv 作为输入。

所以我在我的结构中为 ipiv 分配了一个指针,并在程序的其余部分中使用它。

4

2 回答 2

0

在您对“Bob”的定义中,成员 A 被定义为指向指针的指针,并且根据您的代码,我假设您正在设置一个二维数组。如果是这种情况,分配 b->A[i] 的四个语句应该分配双精度,而不是指向双精度的指针。

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 回答