在 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
我有一个很大的空终止字符串字典,它将在 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