我有一个大型的空终止字符串字典,它将在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有点混淆。
答案 0 :(得分:3)
你有多个问题。第一个是你在main
声明dictionary
是一个或多个数组,这意味着它已经被分配(编译器为你分配数组的内存),这意味着你的赋值是错误的。
另一个问题是数组可能很大,因为大多数系统上的大多数编译器都在堆栈上分配局部变量(包括数组),并且堆栈空间有限。您的数组数组声明将分配200000 * 50
字节,这几乎是10 MB,远远超过大多数默认进程堆栈大小(在Windows上,如果只有一个MB,则为默认堆栈大小)。
当您修复上述问题时,将dictionary
指向指向char
(AllocateMemory
返回的指针)的指针,那么您还有一些其他问题。第一个是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