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; }
好吧,编译器应该呕吐,告诉你int
和char*
不兼容(不久之后它会警告你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