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

WIl*_*JBD 13 c malloc pointers

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

a value of type "int" cannot be used to initialize an entity of type "int (*)[30]"
Run Code Online (Sandbox Code Playgroud)

即这会让我这样一个错误

int(*array)[160] = malloc((sizeof *array) * 10);
Run Code Online (Sandbox Code Playgroud)

并做这样的事情

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;
}
Run Code Online (Sandbox Code Playgroud)

会得到我的

"void *(size_t)" in "memory.c" at line 239 and: "int()" 
Run Code Online (Sandbox Code Playgroud)

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

ren*_*don 17

试试这个:

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]);
}
Run Code Online (Sandbox Code Playgroud)

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

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


Who*_*aig 12

这两个编译对我来说都很好.当你忘了第一个错误是常见#include <stdlib.h>之前,使用内声明的函数表示,相同的(如malloc(size_t)),我也不会忘记这样做.

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

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

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

int func();
Run Code Online (Sandbox Code Playgroud)

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

Warning: implicit declaration of `func` assumed to return `int`
Run Code Online (Sandbox Code Playgroud)

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

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

#include <stdio.h>

// Note: NO prototype for get_str
int main()
{
    char *s = get_str();
    printf("String: %s\n", s);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

好吧,编译器应该呕吐,告诉你int并且char*不兼容(在它警告你get_str被假定返回后不久int).但是,如果你通过告诉编译器以char*某种方式做出某种方式来强制编译器的手:

#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;
}    
Run Code Online (Sandbox Code Playgroud)

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


那么所有这些与你的代码有什么关系呢?通过不包括<stdlib.h>编译器不知道是什么malloc.所以它假定它的形式如下:

int malloc();
Run Code Online (Sandbox Code Playgroud)

然后,通过将结果转换为(int**)您告诉编译器"无论如何,将其设为int**".在链接时,_malloc找到(没有参数签名通过名称像C++一样),连线,你的程序准备派对.但在你的平台int和数据指针是相同的大小,因此你结束了几个不良后果:

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

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

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

在这种情况下,它隐藏了真正的错误,你忽略了为你的编译器提供足够的信息以了解它究竟malloc是做什么的.

  • @WIllJBD第二个更重要.*从不*在编译C时强制转换malloc.它不需要并隐藏此错误,这在"int"与指针大小不同的平台上进行编译时可能会非常糟糕. (5认同)

Dav*_*rtz 5

要分配数组:

int *array = malloc(sizeof(int) * 160 * 10);
Run Code Online (Sandbox Code Playgroud)

然后使用如下代码:

array[10 * row + column] = value;
Run Code Online (Sandbox Code Playgroud)

(row从0到159,包括column0到9,包括0到9).