你使用指针。
具体来说,您使用指向地址的指针,并使用标准 c 库函数调用,您要求操作系统扩展堆以允许您存储所需的内容。
现在,它可能会拒绝,您需要处理它。
下一个问题变成了——你如何要求一个二维数组?好吧,你要求一个指针数组,然后展开每个指针。
例如,考虑一下:
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 */
}
这将为您提供一个二维数组,其中每个元素words[i]
可以具有不同的大小,可以在运行时确定,就像字数一样。
完成后,您将需要free()
通过遍历数组来获取所有结果内存:
for ( i = 0; i < num_words; i++ )
{
free(words[i]);
}
free(words);
如果不这样做,就会造成内存泄漏。
你也可以使用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
这些是相同的,但 Windowswchar_t
经常使用 - 在这种情况下,您将为最后一个零保留一个字节而不是两个 - 它们是 type 的以零结尾的元素type
,而不是单个零字节。这意味着您将在读取和写入方面超出预期。
附录:随心所欲地做,如果您要将缓冲区传递给依赖它们的东西,请注意那些零终止符。