malloc编译错误:类型为“int”的值不能用于初始化int(*)类型的实体

我现在必须尝试过20种方法。 我真的需要帮助,无论我做什么,我都会收到与此类似的错误。

a value of type "int" cannot be used to initialize an entity of type "int (*)[30]" 

即这会让我这样的错误

 int(*array)[160] = malloc((sizeof *array) * 10); 

并做这样的事情

 int** Make2DintArray(int arraySizeX, int arraySizeY) { int** theArray; theArray = (int**) malloc(arraySizeX*sizeof(int*)); int i; for (i = 0; i < arraySizeX; i++) { theArray[i] = (int*) malloc(arraySizeY*sizeof(int)); } return theArray; } 

会得到我的

 "void *(size_t)" in "memory.c" at line 239 and: "int()" 

有没有人有一个解决方案,如何成功分配int [160] [10]的2dArray

这两个编译对我来说都很好。 第一个错误是常见的,当您在使用在相同内容中声明的函数(例如malloc(size_t) )之前忘记#include ,我不会忘记这样做。

C有一些有趣的编译时行为,其中包括调用以前从未见过的函数的能力(既不是原型定义也不是实现)。 在遇到这样的调用时,C假定函数是:

  • 返回int东西
  • 采用未知数量的参数,因此调用者可以传递任何想要的东西(包括错误的东西)。

例如,该函数被隐式假设为以下forms:

 int func(); 

通常你甚至都不会注意到,除了你的编译器发出的警告,报告的结果是:

 Warning: implicit declaration of `func` assumed to return `int` 

如果你是在球上,那么你的警告级别会出现警告,并且会启用错误,并且会抓住这个。

但是如果你不这样做呢? 如果函数返回的“东西”不能用实现int的数据大小来表示内容呢? 例如,如果int是32位,但数据指针是64位怎么办? 例如,假设char *get_str()在您包含的某个头文件中声明,并在您编译并与您的程序链接的.c文件中实现,如下所示:

 #include  // Note: NO prototype for get_str int main() { char *s = get_str(); printf("String: %s\n", s); return 0; } 

好吧,编译器应该呕吐,告诉你intchar*不兼容(不久之后它会警告你get_str被假定为返回int )。 但是如果你通过告诉它以某种方式制作一个char*来强制编译器的手:

 #include  // Note: NO prototype for get_str int main() { char *s = (char*)get_str(); // NOTE: added cast printf("String: %s\n", s); return 0; } 

现在,在没有警告 – 启用错误的情况下,您将获得隐式声明警告,就是这样。 代码将编译。 但它会运行吗? 如果sizeof(int) != sizeof(char*) ,(32位vs 64位)可能不会。 从get_str返回的值是一个64位指针,但调用者假设只返回32位,然后强制它为64位指针。 简而言之,演员隐藏了错误并打开了潘多拉的未定义行为框。


那么所有这些与你的代码有什么关系呢? 通过不包括 ,编译器不知道malloc是什么。 所以它假定它的forms如下:

 int malloc(); 

然后,通过将结果转换为(int**)您告诉编译器“无论如何,将其设为int** ”。 在链接时,找到_malloc (没有参数签名,通过名称像C ++一样),连线,你的程序已准备好派对。 但是在您的平台上int和数据指针的大小不同,因此最终会产生一些不良后果:

  • 演员隐藏了真正的错误。
  • 虚假指针由实际返回指针的一半位制造。
  • 作为伤口盐的残酷剂量,分配的内存被泄露,因为在任何引用它的地方都没有有效的指针(你只是通过保留它的一半来销毁唯一的一个)。
  • 可能是不受欢迎的, 如果在 sizeof(int) == sizeof(int**) 的实现上编译代码将表现出正常行为

所以你在你的32位Debian盒子上构建它,一切看起来都很好。 你把你的作业转交给在他的64位Mac上构建它的教授,它崩溃了,你没能完成作业,没有上课,辍学,并且在接下来的十年里一直在抚摸猫,同时看着Seinfeld在你母亲的地下室重播想知道出了什么问题。 哎哟。

不要像一些银弹一样对待铸造 。 事实并非如此。 在C中,它比人们使用它的频率低得多,如果在错误的地方使用,可以隐藏灾难性的错误。 如果你在代码中找到一个点,如果没有硬编译就无法编译,那么再看看 。 除非你是绝对的,否则确定演员是正确的事情,可能是错误的

在这种情况下,它隐藏了真正的错误,你忽略了为你的编译器提供足够的信息来知道malloc真正做了什么。

试试这个:

 int **array; array = malloc(rows * sizeof(int *)); for (i = 0; i < rows; i++) array[i] = malloc(cols * sizeof(int)); // Some testing for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) array[i][j] = 0; // or whatever you want } for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) printf("%d ", array[i][j]); } 

在你的情况下,行= 160和cols = 10.是一种可能的解决方案。

使用这种方法,您可以使用这两个索引:

要分配数组:

 int *array = malloc(sizeof(int) * 160 * 10); 

然后使用如下代码:

 array[10 * row + column] = value; 

(其中row从0到159(包括0和159), column从0到9(包括0和9)。)

我有一个关于rendon答案的说明:

对于他的代码,Visual C ++为每个“=”操作说: error C2440: '=' : cannot convert from 'void *' to 'int **'

通过做一些更改,它对我有用,但我不确定它是否也一样,所以我害怕编辑他的代码。 相反,这是我的代码,似乎适用于第一印象。

 int **a; a = (int **)malloc(rows * sizeof(int)); for (i = 0; i < rows; i++) { a[i] = (int *)malloc(cols * sizeof(int)); } for (j=0;j 

实际上,我使用自定义struct而不是int来实现它,但我认为无论哪种方式都可行。

不要介意我,我只是使用calloc添加一个例子

 void allocate_fudging_array(int R, int C) { int **fudging_array = (int **) calloc(R, sizeof(int *)); for(int k = 0; k < R; k++) { fudging_array[k] = (int*) calloc(C, sizeof(int)); } } // a helper function to print the array void print2darr(int **arr, int R, int C) { for(int i = 0; i < R; i++) { for(int j = 0; j < C; j++) { printf(" %d ", arr[i][j]); } printf("\n"); } } 

用于存储char *的 2D数组

 char ***array; int rows = 2, cols = 2, i, j; array = malloc(sizeof(char **)*rows); for (i = 0; i < rows; i++) array[i] = malloc(cols * sizeof(char *)); array[0][0] = "asd"; array[0][1] = "qwe"; array[1][0] = "stack"; array[1][1] = "overflow"; for(i=0;i