将malloc用于2D数组时的分段错误

时间:2013-10-06 11:08:35

标签: c

我使用malloc创建了一个二维数组。当我使用printf在for循环中打印数组元素时,一切都很好。但是当我想在main中使用printf时,这些是Segmentation fault: 11.

您能否告诉我以下代码的问题是什么?

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

void initCache(int **cache, int s, int E){
int i, j;
/* allocate memory to cache */
cache = (int **)malloc(s * sizeof(int *)); //set 
for (i = 0; i < s; i++){
    cache[i] = (int *)malloc(E * sizeof(int)); //int

    for(j = 0; j < E; j++){
        cache[i][j]  = i + j;   
        printf("%d\n", cache[i][j]);
    }
  }
}


main()
{
    int **c;

    initCache (c, 2, 2);

    printf("%d\n", c[1][1]);  // <<<<<<<<<< here

}

3 个答案:

答案 0 :(得分:4)

由于您的缓存是2D数组,因此它是int**。要在函数中设置它,请传递int***,而不是int**。否则,对cache内的initCache所做的更改不会影响cmain()的值。

void initCache(int ***cache, int s, int E) {
    int i, j;
    /* allocate memory to cache */
    *cache = (int **)malloc(s * sizeof(int *)); //set 
    for (i = 0; i < s; i++) {
        (*cache)[i] = (int *)malloc(E * sizeof(int)); //int
        for(j = 0; j < E; j++){
            (*cache)[i][j]  = i + j;   
            printf("%d\n", (*cache)[i][j]);
        }
    }
}

现在你可以这样称呼它:

initCache (&c, 2, 2);

答案 1 :(得分:3)

您更改了一个局部变量,该变量不会影响main中的局部变量c

如果要在函数中分配,为什么要传递变量?将其从函数中返回。

int **c = initCache(2, 2);

答案 2 :(得分:1)

您可以使用其他人建议的return***。我将在此处描述return方法。

initCache正在创建和初始化一个合适的数组,但它没有返回它。 cache是指向数据的局部变量。有两种方法可以将此信息提供给调用函数。要么return,要么传入int***并使用它来记录指针值。

我建议:

int** initCache(int **cache, int s, int E){
   ....
   return cache;
}


main()
{
   int **c;
   c = initCache (2, 2);
   printf("%d\n", c[1][1]);   <<<<<<<<<< here
}

====

最后,养成检查错误的习惯非常重要。例如,malloc如果内存不足,将返回NULL。此外,您可能会意外地看到负内存量(如果s为负数)。因此,我会这样做:

cache = (int **)malloc(s * sizeof(int *));
assert(cache);

如果malloc失败,这将结束程序,并告诉你哪条线路失败了。有些人(包括我!)会像这样使用assert略微反对。但是我们都同意这比没有错误检查更好!

您可能需要#include <assert.h>来完成这项工作。