在 main 之外的函数中 malloc 一个大的二维字符串数组

Malloc a large 2D string array in a function outside of main

我有一个很大的空终止字符串字典,它将在 main 中声明为 char dictionary[MAX_WORDS][MAX_WORD_LENGTH],其中 max_words 可以是 200000,最大字长可以是 50。我想 malloc 一些 space 为它加上另一个函数,如:

char ** AllocateMemory (char dictionary[MAX_WORDS][MAX_WORD_LENGTH])
{
    char **p;
    {
        p = (char **)malloc(sizeof(dictionary));
    }
    return p;
}

将在main中调用,如

int main (void)
{
char dictionary[MAX_WORDS][MAX_WORD_LENGTH];

dictionary = AllocateMemory(dictionary);
}

我可以正常访问这段内存吗? (就像另一个循环遍历字典中单词的函数,如 for (i = 0; dictionary[i][0]; i++),然后是每个单词中的字母)。另外我可能在这里遗漏了一些东西但是如果我 malloc space 为它准备好,我已经通过必须声明字典在 main 中创建了大量的 space 吗?请纠正我,我确定我在这里与 malloc 有点混淆。

您有多个问题。首先是你在 main 中声明 dictionary 是一个或多个数组,这意味着它已经分配(编译器为你的数组分配内存),这意味着你的分配是错误的。

另一个问题是数组可能太大了,因为大多数系统上的大多数编译器都在堆栈上分配局部变量(包括数组),而堆栈space是有限的。您的数组声明数组将分配 200000 * 50 字节,这将近 10 MB,远远超过大多数默认进程堆栈大小(在 Windows 上,如果只有一个 MB,则为默认堆栈大小)。

当你修复了上面的问题,并使 dictionary 成为一个指向 char 的指针(什么 AllocateMemory returns),那么你还有一些其他的问题.第一个是 AllocateMemory 分配了错误的大小,另一个是数组的数组 与指向指针的指针相同(参见 this old answer of mine for an explanation). Also, in C you should not cast the result of malloc ,或任何返回 void *.

的函数

您的程序的 "correct" 版本看起来像这样:

char ** AllocateMemory (void)
{
    char **p = malloc(MAX_WORDS * sizeof(*p));
    for (size_t i = 0; i < MAX_WORDS; ++i)
        p[i] = malloc(MAX_WORD_LENGTH + 1);  // +1 for string terminator

    return p;
}

int main (void)
{
    char **dictionary = AllocateMemory();

    // Not you can use `dictionary` as an array of arrays of characters,
    // or an array of strings
}

AllocateMemory 可以 return 类型为 char (*)[MAX_WORD_LENGTH] 的指针,如下所示(为了更简单的理解,使用 typedef)

#include <stdlib.h>

typedef char word[MAX_WORD_LENGTH];
word * AllocateMemory()
{
    word *p;
    {
        p = (word *)malloc(MAX_WORDS*sizeof(word));
    }
    return p;
}

int main (void)
{
    word * dictionary;
    dictionary = AllocateMemory();
    /* Access using dictionary[x][y] */
    return 0;
}

发布的代码有几个问题。

我没有尝试一一列举,而是针对您的问题提供了一个可能的解决方案。

struct dictionary
{
    char words[MAX_WORDS][ MAX_WORD_LENGTH];
};

struct dictionary *AllocateMemory ()
{
    char *p = NULL;

    if( NULL == (p = malloc( sizeof( struct dictionary ) ) ) )
    { // then malloc failed
        perror( "malloc for dictionary failed ");
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    return p;
}  // end function: AllocateMemory


which will be called in main like

int main (void)
{
    struct dictionary * pDictionary = AllocateMemory();

    free( pDictionary);
    return 0;
}  // end function: main