13

到目前为止,我一定已经尝试了 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

4

6 回答 6

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]);
}

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

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

于 2012-12-03T05:25:30.527 回答
13

这两个对我来说都很好。第一个错误很常见,因为您忘记#include <stdlib.h>在使用所述相同(例如malloc(size_t))中声明的函数之前,我没有忘记这样做。

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

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

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

int func();

通常你甚至不会注意到,除了来自编译器的警告,这些警告会报告以下内容:

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

如果你在球上,你的警告级别会在启用警告错误的情况下出现,并且会抓住这一点。

但如果你不这样做呢?如果从函数返回的“事物”不能由实现中的数据大小以内容表示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;
}

好吧,编译器应该呕吐,告诉你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;
}    

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


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

int malloc();

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

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

所以你在你的 32 位 Debian 机器上构建它,一切看起来都很好。你把你的作业交给教授,他在他的 64 位 Mac 上构建它,然后它崩溃了,你不及格,不及格,辍学,在接下来的十年里抚摸这只猫,同时在你妈妈的地下室看 Seinfeld 重播想知道出了什么问题。哎哟。

不要把铸造当作银弹。它不是。在 C 语言中,需要它的频率低于人们使用它的频率,如果用在错误的地方,可能会隐藏灾难性的错误。如果您在代码中发现没有硬转换就无法编译的地方,请再看一遍。除非您绝对、肯定地确定演员阵容是正确的,否则很可能是错误的。

在这种情况下,它隐藏了真正的错误,即您忽略了向编译器提供足够的信息以了解malloc真正的作用。

于 2012-12-03T05:25:41.650 回答
5

分配数组:

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

然后使用如下代码:

array[10 * row + column] = value;

(其中row从 0 到 159(含)和column从 0 到 9(含)。)

于 2012-12-03T05:21:42.380 回答
0

我有一个关于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<rows;j++)
{
    for (i=0;i<cols;i++)
    {
        a[i][j] = 2;
    }
}

实际上,我是用 customstruct而不是ints 来做的,但我认为无论哪种方式都应该有效。

于 2013-07-23T18:46:48.573 回答
0

别介意我只是在添加一个使用 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");
    }
}
于 2013-11-12T16:56:14.213 回答
-1

用于存储字符的二维数组*

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<rows;i++){
  for(j=0;j<cols;j++){
    printf("%s ",array[i][j]);
  }
  printf("\n");
}
于 2014-01-31T22:39:29.017 回答