多次使用malloc函数为什么不行?
编了一个程序,
其中要用到很多很多数组来进行大型的矩阵计算(使用分治法递归实现,所以中间数据特别多)。
定义成静态数组已经不够用了(经测试只能支持到几百*几百的数组相乘)。
所以采用了malloc的形式,
但在运行的时候,却出现 Segmentation fault (core dumped)
经测试发现,如果我连续malloc两三次的话,程序是可以运行的,
一旦我连续malloc好多次,程序在运行的时候在某个malloc处就会出错而终止。尽管我测试的矩阵很小,不可能内存不够。
程序本身应该是没有问题的,因为若使用静态数组的话,一切正常。
这样的问题,可能是出在哪里呢?
void STRASSEN(arg)
struct thread_args *arg;
{
float **A12,**A21;
float **B12,**B21;
float **C11,**C12,**C21,**C22;
float **MM1,**MM2;
struct thread_args thread[7];
int i,j;
int n = arg->n;
int m = n/2;
if (n == TN) {
MATRIX_MULTIPLY(n,arg->A,arg->B,arg->C);
} else {
A12=(float **)malloc(m*sizeof(float *));
A21=(float **)malloc(m*sizeof(float *));
B12=(float **)malloc(m*sizeof(float *));
B21=(float **)malloc(m*sizeof(float *));
C11=(float **)malloc(m*sizeof(float *));
C12=(float **)malloc(m*sizeof(float *));
C21=(float **)malloc(m*sizeof(float *));
C22=(float **)malloc(m*sizeof(float *));
MM1=(float **)malloc(m*sizeof(float *));
MM2=(float **)malloc(m*sizeof(float *));
if (NULL==A12||NULL==A21||NULL==B12||NULL==B21){
_error(ERR_MEM);
}
if (NULL==C11||NULL==C12||NULL==C21||NULL==C22||NULL==MM1||NULL==MM2) {
_error(ERR_MEM);
}
for (i=0;i<m;i++) {
A12[i]=(float *)malloc(m*sizeof(float));
A21[i]=(float *)malloc(m*sizeof(float));
B12[i]=(float *)malloc(m*sizeof(float));
B21[i]=(float *)malloc(m*sizeof(float));
C11[i]=(float *)malloc(m*sizeof(float));
C12[i]=(float *)malloc(m*sizeof(float));
C21[i]=(float *)malloc(m*sizeof(float));
C22[i]=(float *)malloc(m*sizeof(float));
MM1[i]=(float *)malloc(m*sizeof(float));
MM2[i]=(float *)malloc(m*sizeof(float));
if (NULL==A12[i]||NULL==A21[i]||NULL==B12[i]||NULL==B21[i]||NULL==C11[i]||NULL==C12[i]||NULL==C21[i]||NULL==C22[i]||NULL==MM1[i]||NULL==MM2[i]) {
_error(ERR_MEM);
}
}
//省略计算各矩阵的步骤
// 分线程再次调用STRASSEN, 传入的参数thread[i]中包含了float **A,**B,**C,分别也是一个动态分配的二位数组
for (i = 0; i < 7; i++) {
pthread_t id;
if(pthread_create(&id,NULL,(void*)STRASSEN,(void*)&thread[i])) {
perror("pthread_create");
exit(1);
}
pthread_join(id,NULL);
}
//省略一些
for (i=0;i<m;i++) {
free(A12[i]);
free(A21[i]);
free(B12[i]);
free(B21[i]);
free(C11[i]);
free(C12[i]);
free(C21[i]);
free(C22[i]);
free(MM1[i]);
free(MM2[i]);
}
free(A12),free(A21),free(B12),free(B21);
free(C11),free(C12),free(C21),free(C22),free(MM1),free(MM2);
}
}
翻译为:
所谓的段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。一旦一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现了
楼主参考。
[解决办法]
段错误一般为指针错误,你可以使用GDB模式调试,当程序崩溃后使用bt,看下在什么地方出的问题。
[解决办法]
程序本身应该是没有问题的,因为若使用静态数组的话,一切正常。
这个不一定,因为某些内存泄露和越界是程序运行中无法发现的,所以可能的问题还是程序的问题
还是要通过分析程序及利用调试工具来发现程序中的错误
[解决办法]
如果用gdb调试的话,可以看出段错误发生在哪一行代码上
[解决办法]
int get_mem_for_data(int x, int y, double*** data)
{
if(NULL == (*data = (double**)malloc(x*sizeof(double*))))return (-1);
for(int i = 0; i < x; i++)
(*data)[i] = (double*)malloc(y*sizeof(double));
static int k = 0;
printf("%d\n", k++);
return (0);
}
int main(int argc, char* argv[])
{
printf("Hello World!\n");
double** data[1000];
for(int i = 0; i < 1000; i++)
get_mem_for_data(100, 100, &data[i]);
data[999][99][99] = 1.0;
printf("%f\n", data[999][99][99]);
//释放内存你,略。
return 0;
}
调用了999次,也没问题啊?