我有一个以null结尾的字符串的大字典,它将在main中声明为char dictionary[MAX_WORDS][MAX_WORD_LENGTH]
,其中最大单词数可以是200000,最大单词长度可以是50。我想用另一个函数为它分配一些空间,比如:
char ** AllocateMemory (char dictionary[MAX_WORDS][MAX_WORD_LENGTH])
{
char **p;
{
p = (char **)malloc(sizeof(dictionary));
}
return p;
}
它将主要像一样被调用
int main (void)
{
char dictionary[MAX_WORDS][MAX_WORD_LENGTH];
dictionary = AllocateMemory(dictionary);
}
我可以用正常的方式访问这个内存吗?(就像另一个函数一样,它循环遍历字典中的单词,比如for (i = 0; dictionary[i][0]; i++)
,然后遍历每个单词中的字母)。此外,我可能在这里缺少了一些东西,但如果我为它分配了malloc空间,那么我已经通过声明字典来创建了大量的空间?请纠正我,我确信我只是有点和malloc混淆了。
您有多个问题。第一种情况是,在main
中,您将dictionary
声明为一个或多个数组,这意味着它已经被分配(编译器为您的数组分配内存),这意味着您的分配是错误的。
另一个问题是数组可能太大,因为大多数系统上的大多数编译器都在堆栈上分配局部变量(包括数组),并且堆栈空间有限。数组数组声明将分配200000 * 50
字节,这几乎是10 MB,远远超过大多数默认进程堆栈大小(在Windows上,如果只有一MB,则为默认堆栈大小)。
当您修复了上述问题,并使dictionary
成为指向char
的指针(AllocateMemory
返回的内容)时,就会出现其他一些问题。第一种是AllocateMemory
分配了错误的大小,另一种是数组的与指向指针的指针不同(请参阅我的旧答案以获得解释)。此外,在C中,您不应该强制转换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
}
发布的代码有几个问题。
我没有试图一一列举,而是为你的问题提供了一个可能的解决方案。
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
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;
}