Malloc在main之外的函数中的大型2D字符串数组
我有一个以null结尾的字符串的大字典,主要声明为char dictionary[MAX_WORDS][MAX_WORD_LENGTH],其中MAX_WORDS可以是200000,MAX WORD LENGTH可以是50。我想用另一个函数为它分配一些空间,如:Malloc在main之外的函数中的大型2D字符串数组,c,arrays,malloc,C,Arrays,Malloc,我有一个以null结尾的字符串的大字典,主要声明为char dictionary[MAX_WORDS][MAX_WORD_LENGTH],其中MAX_WORDS可以是200000,MAX WORD LENGTH可以是50。我想用另一个函数为它分配一些空间,如: char ** AllocateMemory (char dictionary[MAX_WORDS][MAX_WORD_LENGTH]) { char **p; { p = (char **)malloc(
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);
}
我能以正常方式访问此内存吗?类似于另一个函数,它循环遍历字典中的单词,如i=0;字典[i][0];i++,然后是每个单词中的字母。另外,我可能在这里遗漏了一些东西,但是如果我为它添加了malloc空间,我已经通过声明字典创建了大量的空间?请纠正我,我肯定我只是有点困惑在这里与马洛克 您有多个问题。首先,您主要是将字典声明为一个或多个数组,这意味着它已经被分配。编译器为数组分配内存,这意味着您的分配是错误的 另一个问题是数组可能太大,因为大多数系统上的大多数编译器都分配局部变量,包括堆栈上的数组,并且堆栈空间有限。数组数组声明将分配200000*50字节,这几乎是10 MB,远远超过Windows上的大多数默认进程堆栈大小(如果只有单个MB,则默认堆栈大小) 当您解决上述问题,并使dictionary成为指向char的指针,而AllocateMemory返回的是char,那么您还有一些其他问题。第一个原因是AllocateMemory分配了错误的大小,另一个原因是数组数组与指向指针的指针不同,请参见。此外,在C语言中,您或任何返回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
}
AllocateMemory可以返回char*[MAX\u WORD\u LENGTH]类型的指针,如下所示,以便于理解
#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
啊,我明白了。这更有道理。那么访问char字典**与访问字典[][]是一样的吗?为像单个字符串这样的小东西分配空间值得吗?如果是这样的话,我需要另一个函数来实现,其中malloc行是char*p=mallocMAX_WORDS*sizeofp+1;?然后在main char*string=AllocateMemory中;为什么要使数据结构复杂化?现在需要将一堆指针传递给free,而发布的答案缺少对每次调用malloc返回值的检查,以确保操作成功。我给出了最好的答案,因为它基本上清楚地解释了错误所在以及如何修复。@user3629249这不是一个复杂的数据结构,在编写C代码时,这是很常见的。是的,它不做任何错误检查,因为这会使代码变得混乱,更难阅读。@JoachimPileborg你的意思是不应该在C中使用void*?你提到的链接中的答案明确提到你不投,而不是你不需要投,也就是说,答案给出了不投的原因,这并不意味着我们不应该投。在C++中强制强制显式空格式的创建,有助于避免隐式类型转换引起的错误。即使对于C编译器,您也可以启用这样的警告,例如gcc中的-Wc++-compat。没有必要在C中强制转换malloc,我也没有理由就此与您争论,但我发现您不同意这一点,这让我问您,是否有什么东西使您能够像应该的那样在C中强制转换malloc。请坚持使用C语言。这里是对的一个解释。我不是在谈论特定的语言,也不是在谈论malloc,而是在谈论一般的编码实践。因为在C中发现了这样的问题,所以C++变得更加类型安全,它允许从空洞*中隐式转换,这是一种不安全的操作。我们仍然需要C中的void*,因为它是表示泛型指针的唯一方法。因此,与其建议类型不安全操作,不如让编译器警告这种转换,并显式强制转换,我们确信它是类型安全的。我不是说其他语言,请坚持使用C语言。如果你问你的编译器,这意味着你使用了错误的编译器和语言。我重复一遍,请坚持C语言,我们不能在C和C++之间有语言。人们在C或C++中都可以编码。笼统地说不应该在C中强制转换总是意味着纯C,这不是一个好的编码建议。如果有一些事情你不理解/接受,请告诉我。我放弃了。祝您有个美好的一天。