【问题标题】:Segmentation fault in allocating a large array in C在 C 中分配大数组时出现分段错误
【发布时间】:2020-08-02 03:54:16
【问题描述】:

我打算分配一个大小为1073741824(例如,相当于1GB)的大型数组,然后随机读取它,但我得到分段错误(核心转储),因为我只定义了我检查过的数组,我喜欢:

unsigned int size = 1073741824;
short arr = malloc(size * sizeof(short));

我也尝试按如下方式进行转换,但仍然是同样的问题:

unsigned int size = 1073741824;
short *arr = (short*) malloc(size * sizeof(short));

ulimit 命令也返回unlimited

那我做错了什么?

【问题讨论】:

  • 你可能需要一个指针:short *arr = malloc(...).
  • 正如@MOehm 所建议的,这不是malloc 的正确使用。查看:es.cppreference.com/w/c/memory/malloc,查看示例
  • 你说得对,我很抱歉我编辑了我的问题,这就是我编写和测试代码的方式,但无论如何它仍然返回分段错误。
  • 你测试malloc的返回值了吗?
  • 请注意,short 至少有 2 个字节宽,因此您尝试分配至少 2 GB,而不仅仅是一个。分配本身到段错误会令人惊讶,但它可能会合理地失败,返回NULL。您必须始终检查分配失败。如果它确实失败了,但您尝试使用生成的空指针,就好像它指向一个对象一样,那么分段错误将是一个合理的结果。

标签: c gcc segmentation-fault malloc


【解决方案1】:

问题的可能原因是malloc() 未能在您的系统上分配接近 2GB 的内存。您必须检查返回值:如果malloc() 失败,则返回一个无法取消引用的NULL 指针。

此外,您的第一个代码片段将arr 定义为short,而不是short *

这是您应该使用的典型代码模式:

    unsigned int size = 1073741824;
    short *arr = malloc(size * sizeof(short));
    if (arr == NULL) {
        fprintf("cannot allocate memory for %u shorts\n", size);
        exit(1);
    }

【讨论】:

    【解决方案2】:

    我认为您的问题是函数 malloc 由于数组的大小而返回 NULL。直接使用 malloc 很容易出错。因此最好使用这样的宏函数:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define NEW_ARRAY(ptr, length) \
    { \
            (ptr) = malloc((size_t) (length) * sizeof (ptr)[0]); \
            if ((ptr) == NULL) { \
                    fputs("error: Memory exhausted\n", stderr); \
                    exit(EXIT_FAILURE); \
            } \
    }
    
    
    int main(void)
    {
        unsigned int arrLen = 1073741824;
        short *arr;
    
        NEW_ARRAY(arr, arrLen);
        /*...*/
        free(arr);
        return 0;
    }
    

    【讨论】:

    • 像这样将检查包装在宏中是一种反模式——在大多数情况下,调用 malloc 的函数应该在 malloc 失败时向其调用者返回错误指示,而不是无条件退出。如果您确实必须使用全局包装器,请使用函数,而不是宏。
    • @ChrisDodd 如果宏是本地应用程序的所需行为,则不是。如果这不是您想要的行为,您可以跳过 NULL 检查。如果分配被定义为一个函数而不是你需要传递元素大小,那么代码就会变得更加冗长(并且更容易出错)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    • 2013-11-10
    相关资源
    最近更新 更多