C语言中的Malloc内存损坏问题

5
我是一名有用的助手,可以翻译文本。

我遇到了使用 malloc 的问题。

我有一个名为 jacobi_gpu 的函数需要被多次调用:

int main(int argc, char* argv[]){

    /* ... */

    int totalrot=0;
    while(nrot>0){
        iter++;
        nrot=jacobi_gpu(a,q, tol, dimmat);
        totalrot+=nrot;

        printf("iter =%3d  nrot=%3d\n",iter, nrot);
    }

    /* ... */
}

参数 a、q、tol 和 dimmat 已正确初始化。A 和 Q 是两个方阵,dimmat 是它们的维度。

这是我的代码:

int jacobi_gpu(double A[], double Q[], double tol, long int dim){
    int nrot, p, q, k, tid;
    double c, s;
    double *mc, *vc;

    printf("jacobi begins \n");

    mc   = (double *)malloc(2 * dim * sizeof(double));
    vc   = (double *)malloc(2 * dim * sizeof(double));

    if( mc == NULL || vc == NULL){
        fprintf(stderr, "pb allocation matricre\n");
        exit(1);
    }

    nrot = 0;

    for(k = 0; k < dim - 1; k++){
        eye(mc, dim);
        eye(vc, dim);

        for(tid = 0; tid < floor(dim /2); tid++){
            p = (tid + k)%(dim - 1);
            if(tid != 0)
                q = (dim - tid + k - 1)%(dim - 1);
            else
                q = dim - 1;

            //printf("p = %d | q = %d\n", p, q);
            if(fabs(A[p + q*dim]) > tol){

                nrot++;
                symschur2(A, dim, p, q, &c, &s);

                mc[2*tid] = p;        vc[2 * tid] = c;
                mc[2*tid + 1] = q;    vc[2*tid + 1] = -s;

                mc[2*tid + 2*(dim - 2*tid) - 2] = p;
                vc[2*tid + 2*(dim - 2*tid)   - 2 ] = s;

                mc[2*tid + 2*(dim - 2*tid) - 1] = q;
                vc[2 * tid + 2*(dim - 2*tid) - 1 ] = c;     
            }
        }

        affiche(mc,dim,2,"Matrice creuse");
        affiche(vc,dim,2,"Valeur creuse");

    }
    printf("end\n");
    free(mc);
    free(vc);
    return nrot;
}

我的问题出现在对mc变量进行malloc调用时:

*** glibc detected *** ./jacobi_gpu: double free or corruption (!prev): 0x00000000022944a0 ***
    *** glibc detected *** ./jacobi_gpu: malloc(): memory corruption: 0x0000000002294580 ***

有什么建议吗?

[编辑]

  • 函数eye初始化一个单位矩阵。
  • 函数affiche用行和列显示矩阵。第一个参数是矩阵,第二个参数是行数,第三个参数是列数。

更多解释

矩阵mc的目的是存储变量p和q。这些变量包含列索引。 矩阵vc的目的是存储这些列中包含的值。 例如,如果矩阵mc的第一行是0和5(p = 0,q = 5),那么意味着矩阵vc中的值将在列0和5中。 如果矩阵的第五行是2 3(p = 2,q = 3),那么意味着矩阵vc中第五行的值将在列2和3中。

希望这次我表述更清楚了。

谢谢你的帮助。


2
当您使用调试器逐步执行代码时会发生什么? - nmichaels
1
eye() 函数是做什么的?它在什么情况下会失败?即,它是在第一次调用 malloc() 后失败还是在多次调用后失败? - e.James
那么,affiche()函数是做什么用的? - e.James
1
@james affiche() 被翻译为海报,因此我猜测它是一个输出包装器。 - fbstj
4个回答

6

单位矩阵始终是方阵,但mc不是。当您调用eye(mc,dim)时,我怀疑eye会将mc视为dim乘dim的矩阵,而实际上它是一个2乘dim的矩阵,并写入未分配的内存。


2
啊,eye() 很重要 :) - e.James

2

在调用 malloc() 时,你没有为方阵分配足够的内存。正确的大小应该是 dim 的平方,而不仅仅是 2*dim

以下代码可以解决这个问题:

mc   = (double *)malloc(dim * dim * sizeof(double));
vc   = (double *)malloc(dim * dim * sizeof(double)); 

因此,矩阵操作可能会覆盖malloc的记账信息。 - Fred Foo
1
不,这是我的矩阵的正确维度。该矩阵包含2列和N行。该矩阵的目的是存储值p和q。 - Dimitri
@e.james 他到底在写入未分配的内存的哪里?他所有的数组索引表达式最终都落在0和2*dim之间。 - Null Set
1
@Dimitri:你在问题中说你的矩阵是方阵。 - nmichaels
@Null Set:真实故事。问题中提到的方阵让我有些困惑。 - e.James
显示剩余4条评论

0
据我所知,double free or corruption (!prev) 的错误意味着在同一个指针上多次调用 free() 函数,你的其他函数可能也会这样做(我怀疑是 affiche() 函数)。或许你可以尝试在命令行中输入 export MALLOC_CHECK_=0 后重新运行程序?

0

你的代码中可能存在栈内存崩溃。使用调试选项编译并通过 valgrind 运行代码,它会告诉你问题所在。

顺便说一句,在 C 中将 malloc 的结果强制转换是一个坏习惯。不要这样做,否则它可能隐藏了包含正确头文件的诊断信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接