访问使用malloc

时间:2017-03-04 10:04:21

标签: c arrays multidimensional-array segmentation-fault malloc

以下是我正在编写的程序的简化摘录。我在访问数组末尾的元素时遇到了问题。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(int n, char *args[n]){

    // create 4D array scores[10000][100][100][100] on heap

    uint64_t arraySize = 1;     // this avoids overflow
    arraySize *= 10000;
    arraySize *= 100;
    arraySize *= 100;
    arraySize *= 100;

    int (*scores)[10000][100][100] = malloc(arraySize);

    for (int i = 0; i < 10000; i++) {
      for (int j = 0; j < 100; j++) {
            printf("%d, %d, %d\n", i, j, scores[i][j][0][0]);
      }
    }
  }

程序循环通过4D数组得分并作为测试我打印数组的内容。循环按计划开始,以&#34; i j ,0&#34;格式打印。对于每个 i j ,直到最后一次成功&#34; 25,0,0和#34;。
从这一点开始,我得到随机数而不是0,从&#34; 25,1,1058528&#34;开始。直到&#34; 25,45,1241744152&#34;然后是&#34;分段错误(核心转储)&#34;。

在摆弄后,我发现第一个非零数组成员得分[25] [0] [7] [64]

所以我想我的空间已经用完了,所以访问内存我不应该这样做吗?如果有人知道或了解我如何解决这个问题,我真的很感激。

我的电脑正在运行Ubuntu 16.10 64bit,有16GB内存和16GB交换

修改

在实施以下建议后,我得到&#34; calloc的返回值:无法分配内存&#34;

int (*scores)[100][100][100] = calloc(arraySize, sizeof(int));

if (scores == NULL) {
  perror("calloc");
  return 1;
}

如果我注释掉新的if语句(并运行for循环),我会立即得到seg错误。如果我使用malloc:

,也会发生这种情况
int (*scores)[100][100][100] = malloc(arraySize * sizeof(int));

为什么会这样?当然我的系统有足够的内存 干杯

3 个答案:

答案 0 :(得分:3)

  • 检查malloc()的返回值,并确定是否未能分配。
  • 您忘了乘以int
  • 的大小
  • result的类型应为int (*)[100][100][100],而不是int (*)[10000][100][100]
  • 使用通过malloc()分配但尚未初始化的缓冲区的值调用未定义的行为,所以不要这样做。

试试这个:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(int n, char *args[n]){

    // create 4D array scores[10000][100][100][100] on heap

    uint64_t arraySize = 1;     // this avoids overflow
    arraySize *= 10000;
    arraySize *= 100;
    arraySize *= 100;
    arraySize *= 100;

    int (*scores)[100][100][100] = calloc(arraySize, sizeof(int));

    if (scores == NULL) {
      perror("calloc");
      return 1;
    }

    for (int i = 0; i < 10000; i++) {
      for (int j = 0; j < 100; j++) {
            printf("%d, %d, %d\n", i, j, scores[i][j][0][0]);
      }
    }
}

答案 1 :(得分:1)

指向可变长度数组的指针不使用正确的数组大小。

数组是:[10000][100][100][100]

但指针是:[100][10000][100][100]

你需要将数组大小乘以对象的大小,在这种情况下大小为int类型。

指针定义应为:

int (*scores)[100][100][100] = malloc(arraySize*sizeof(int));

未初始化已分配的元素。阅读它们会产生不确定的价值。

存储需要分配的字节大小的正确类型是size_t,而不是uint64_t。

分配数组的正确方法之一是:

const size_t bytes = sizeof( int[10000][100][100][100] );
int (*scores)[100][100][100] = malloc( bytes );

(当然这假设size_t可以代表该值。)

答案 2 :(得分:-3)

你有没有尝试过:

int (*scores)[10000][100][100] = malloc(sizeof(int)*arraySize);

再见。