到现在为止,我肯定已经试过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()"
有没有人能解决如何成功地分配2darray的int[160][10]
最佳答案
这两个对我来说都很好。第一个错误是常见的,当您在使用上述函数(例如#include <stdlib.h>
)中声明的函数之前忘记malloc(size_t)
,而我没有忘记这样做。
c有一些有趣的编译时行为,其中包括调用以前从未见过的函数的能力(既没有原型定义也没有实现)。在遇到这种调用时,C假设函数为:
返回int
接受未知数量的参数,以便调用方可以传递它想要的任何内容(包括错误的内容)。
例如,函数被隐式假定为:
int func();
通常情况下,您甚至不会注意到,除非编译器发出警告,报告以下内容:
Warning: implicit declaration of `func` assumed to return `int`
如果你在球上,你有你的警告级别出现警告作为错误启用,并将抓住这一点。
但如果你没有呢?如果函数返回的“thing”不能用实现中的数据大小来表示呢?例如,如果
int
是32位的,而数据指针是64位的呢?例如,假设int
是在您不包含的头文件中声明的,并且是在您编译并链接到您的程序的.c文件中实现的,如下所示:#include <stdio.h>
// Note: NO prototype for get_str
int main()
{
char *s = get_str();
printf("String: %s\n", s);
return 0;
}
好吧,编译器应该吐出来,告诉您
char *get_str()
和int
不兼容(在它警告您char*
被假定返回get_str
后不久)。但是,如果通过告诉编译器以某种方式生成int
来强制编译器的手:#include <stdio.h>
// Note: NO prototype for get_str
int main()
{
char *s = (char*)get_str(); // NOTE: added cast
printf("String: %s\n", s);
return 0;
}
现在,如果不启用错误警告,您将得到一个隐式声明警告,就这样。代码将被编译。但它会跑吗?如果
char*
!=sizeof(int)
,(32位对64位)可能不是。从sizeof(char*)
返回的值是一个64位指针,但调用者假设只返回32位,然后将其强制为64位指针。简言之,演员们隐藏了错误,打开了潘多拉未定义行为的盒子。那么所有这些与你的代码有什么关系呢?不包含
get_str
编译器就不知道<stdlib.h>
是什么。所以它假设它的形式是:int malloc();
然后,通过将结果强制转换为
malloc
,您将告诉编译器“无论结果如何,都将其设为(int**)
”。在链接时,发现“cc>”(没有参数签名,如C++的名字窜改),有线,你的程序已经准备好了。但是在您的平台上int**
和数据指针的大小不同,因此您最终会产生一些不希望看到的结果:演员隐藏了真正的错误。
伪指针是由实际返回指针的一半位生成的。
作为伤口上的一剂毒药,分配的内存被泄露了,因为在任何地方都没有有效的指针引用它(你只保留了其中的一半就销毁了唯一的一个)。
可能是最不受欢迎的,如果在
_malloc
的实现上编译,代码将显示正常行为。所以你在你的32位Debian盒子上做这个,看起来一切都很好。你把作业交给教授,教授在64位的Mac电脑上做作业,作业失败了,上课不及格,大学退学了,接下来的十年里,你一边在妈妈的地下室看《宋飞》重播,一边抚摸猫,不知道出了什么事。哎哟。
不要像对待银弹一样对待铸造。在C语言中,它的使用频率远远低于人们使用它的频率,而且如果在错误的地方使用,可能会隐藏灾难性的错误。如果在代码中发现没有硬转换就无法编译的地方,请再次查看。除非你绝对肯定演员是正确的,否则很有可能是错误的。
在本例中,它隐藏了真正的错误,即您忽略了向编译器提供足够的信息以了解
int
真正的功能。