【问题标题】:How to allocate big sized array ( using dynamic memory allocation on heap) inside a function如何在函数内分配大型数组(在堆上使用动态内存分配)
【发布时间】:2017-06-25 11:36:25
【问题描述】:

是否可以在堆上分配一个数组,即使它是在一个函数内的范围内?这是我的 C 程序:

    void SimpleTextEditor()
    {
        char textEditor[1000000];
        char operationText[1000002];
        //do something with the arrays
    }

这会导致 stackOverflow 异常,原因很明显,我试图分配两个大型数组。如果我将任何一个数组移到函数之外并使其成为全局变量(文件级变量),那么它将作为全局变量在堆上分配。

但我不想让我的变量全局化。是不是不能用malloc和calloc为数组动态分配内存?

【问题讨论】:

  • char *textEditor = malloc(1000000); ... free(textEditor);
  • 你能用static吗?
  • “...因为全局变量是在堆上分配的”——你是从哪里得到这个想法的?
  • 我在某处读过它。不要回忆链接以获得确切的参考。如果我错了,请纠正我。我是 C# 的 C 新手

标签: c arrays malloc


【解决方案1】:

绝对可以使用malloc()calloc() 来动态分配内存。只需将它们分配到函数或main(),如果您不想将它们设为全局。处理大数据时,最好在堆上分配空间,以防您需要为更多数据腾出更多空间。

  • 使用malloc()时:

    malloc() 在堆上分配请求的内存,然后返回一个指向它的void* 指针。

    示例:

    char *textEditor = malloc(1000000);
    char *operationText = malloc(1000002);
    
  • 使用calloc()时:

    calloc() 在堆上分配请求的内存,然后返回一个指向它的void* 指针。将内存设置为 0。

    示例:

    char *textEditor = calloc(1000000, sizeof * textEditor);
    char *operationText = calloc(1000002, sizeof * operationText);
    
  • 请务必在最后安全地free() 这些。

    free() 释放先前由malloc()calloc()realloc() 分配的内存。

    示例:

    free(textEditor);
    textEditor = NULL;
    
    free(operationText);
    operationText = NULL;
    

注意:malloc()calloc() 都可以在错误时返回 NULL,因此最好检查它们。你可以这样检查:

if (textEditor == NULL || operationText == NULL) {
    /* handle exit */

【讨论】:

  • 来自 C# 背景,calloc char *textEditor = calloc(1000000, sizeof * textEditor); 的允许语法对我来说真的很奇怪。为了清楚起见,我可能会把它写成char *textEditor = calloc(1000000, sizeof (char));
  • @RBT 也可以。我来自 C 背景,所以我觉得 char *textEditor = calloc(1000000, sizeof * textEditor); 不错。但是他们都做同样的事情,如果你选择sizeof(char),没有问题。
【解决方案2】:

如果我将任何一个数组移出函数并使其 全局(文件级变量)然后它作为全局变量工作 在堆上分配。

这是错误的假设。在文件范围内定义的数组很可能放置在 data segment 内,或者更具体地说是在 .bss 段内,因为没有给出明确的初始化程序。

但我不想让我的变量全局化。是不是不可能 使用 malloc 和 calloc 为数组动态分配内存?

当然可以使用malloc 和朋友动态分配内存。然而,因为大小在编译时是已知的,更好的选择可能是将两个数组都声明为static

void SimpleTextEditor()
{
    static char textEditor[1000000];
    static char operationText[1000002];
     //do something with the arrays
}

【讨论】:

  • 所以一个静态数组变量,即使它是局部作用域的函数,它也不会进入堆栈内存区域。是吗?
  • @RBT:没错。它将进入数据段,就像全局变量一样。唯一的区别在于范围。
  • 我的应用是单线程数据结构相关的程序。我真的应该担心@M.M 担心这个解决方案不是线程安全的吗?程序支持重入的能力如何影响静态变量?
  • @RBT:静态变量在调用之间是“共享的”。在函数调用之间保留相同的数据。只要您不计划对SimpleTextEditor 进行递归调用(直接或间接),那么在实践中就没有关系。
  • 当我尝试释放静态变量warning: attempt to free a non-heap object ‘textEditor’ [-Wfree-nonheap-object] 时收到警告,警告很明显,但我只是想知道如何释放数据段和 bss 等特殊区域中的分配空间一旦我的函数完成执行。
【解决方案3】:

难道不能使用 malloc 和 calloc 为数组动态分配内存吗?

当然可以:

char *textEditor = malloc(1000000);
char *operationText = malloc(1000002);
//do something with the arrays
free(operationText);
free(textEditor);

(注意:如果需要,您可以使用1000000*sizeof(char),但sizeof(char) 始终为1)

【讨论】:

    猜你喜欢
    • 2020-05-11
    • 2011-09-14
    • 2018-09-17
    • 2022-01-15
    • 2010-12-11
    • 1970-01-01
    • 2013-04-04
    • 2013-10-18
    相关资源
    最近更新 更多