Raf*_*fay 12 c memory arrays dynamic-memory-allocation
我怎么能对数组使用动态内存分配?
例如,下面是一个数组,其中我从.txt文件中读取单个单词并在数组中逐字保存:
码:
char words[1000][15];
Run Code Online (Sandbox Code Playgroud)
这里1000定义了数组可以保存的单词数,每个单词可以包含不超过15个字符.
现在我希望该程序应该为它计算的单词数量动态分配内存.例如,.txt文件可能包含大于1000的单词.现在我希望程序应该计算单词数并相应地分配内存.
由于我们不能使用变量代替[1000],因此我对如何实现逻辑完全空白.请帮助我这方面.
小智 23
你使用指针.
具体来说,您使用指向地址的指针,并使用标准的c库函数调用,您要求操作系统扩展堆以允许您存储所需的内容.
现在,它可能会拒绝,你需要处理.
接下来的问题是 - 你如何要求2D阵列?好吧,你要求一个指针数组,然后展开每个指针.
举个例子,考虑一下:
int i = 0;
char** words;
words = malloc((num_words)*sizeof(char*));
if ( words == NULL )
{
/* we have a problem */
printf("Error: out of memory.\n");
return;
}
for ( i=0; i<num_words; i++ )
{
words[i] = malloc((word_size+1)*sizeof(char));
if ( words[i] == NULL )
{
/* problem */
break;
}
}
if ( i != num_words )
{
/* it didn't allocate */
}
Run Code Online (Sandbox Code Playgroud)
这将为您提供一个二维数组,其中每个元素words[i]可以具有不同的大小,在运行时可以确定,就像单词的数量一样.
完成后,您需要free()通过遍历数组来获得所有结果内存:
for ( i = 0; i < num_words; i++ )
{
free(words[i]);
}
free(words);
Run Code Online (Sandbox Code Playgroud)
如果不这样做,您将创建内存泄漏.
你也可以用calloc.区别在于调用约定和效果 - calloc初始化所有内存0而malloc不是.
如果需要在运行时调整大小,请使用realloc.
另外,重要的是,请注意我使用过的word_size + 1.C中的字符串是零终止的,这需要额外的字符,您需要考虑.为了确保我记住这一点,我通常将变量word_size的大小设置为单词大小应该是什么(字符串的长度与我期望的一样),并明确地将malloc中的+1保留为零.然后我知道分配的缓冲区可以采用一串word_size字符.不这样做也没关系 - 我这样做是因为我喜欢以明显的方式明确地解释零.
这种方法也有一个缺点 - 我最近明确将此视为一个传送的错误.请注意我写的(word_size+1)*sizeof(type)- 但想象一下我写的word_size*sizeof(type)+1.对于sizeof(type)=1这些是相同的事情,但Windows使用wchar_t非常频繁 - 在这种情况下,您将为您的最后一个零而不是两个保留一个字节 - 它们是零终止的类型元素type,而不是单个零字节.这意味着你将在读写时超支.
附录:按照你喜欢的方式做它,如果要将缓冲区传递给依赖它们的东西,请注意那些零终止符.
虽然Ninefingers 使用指针数组提供了答案,但只要内部数组的大小是常量表达式,您也可以使用数组数组.这个代码更简单.
char (*words)[15]; // 'words' is pointer to char[15]
words = malloc (num_words * sizeof(char[15]);
// to access character i of word w
words[w][i];
free(words);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
72395 次 |
| 最近记录: |