为数组使用动态内存分配

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初始化所有内存0malloc不是.

如果需要在运行时调整大小,请使用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,而不是单个零字节.这意味着你将在读写时超支.  

附录:按照你喜欢的方式做它,如果要将缓冲区传递给依赖它们的东西,请注意那些零终止符.


Hea*_*ink 7

虽然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)