Malloc在main之外的函数中的大型2D字符串数组

时间:2015-11-17 08:37:18

标签: c arrays malloc

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

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空间用于它,我已经在main中创建了大量空间,无论如何必须声明字典?请纠正我,我确定我在这里与malloc有点混淆。

3 个答案:

答案 0 :(得分:3)

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

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

当您修复上述问题时,将dictionary指向指向charAllocateMemory返回的指针)的指针,那么您还有一些其他问题。第一个是AllocateMemory分配错误的大小,另一个是数组数组与指针指针相同(参见this old answer of mine for an explanation)。另外,在C中你should not cast the result of malloc,或者任何返回void *的函数。

程序的“正确”版本看起来像这样:

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
}

答案 1 :(得分:2)

AllocateMemory可以返回类型为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;
}

答案 2 :(得分:2)

发布的代码存在一些问题。

我没有尝试全部枚举它们,而是为您的问题提供了一个可能的解决方案。

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