对数组使用动态内存分配 [英] Using Dynamic Memory allocation for arrays

查看:70
本文介绍了对数组使用动态内存分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该如何为数组使用动态内存分配?

How am I supposed to use dynamic memory allocations for arrays?

例如,这里是以下数组,我从 .txt 文件中读取单个单词并将它们逐字保存在数组中:

For example here is the following array in which i read individual words from a .txt file and save them word by word in the array:

代码:

char words[1000][15];

这里 1000 定义了数组可以保存的单词数,每个单词不能超过 15 个字符.

Here 1000 defines the number of words the array can save and each word may comprise of not more than 15 characters.

现在我希望该程序应该为它计数的字数动态分配内存.例如,一个 .txt 文件可能包含大于 1000 的单词.现在我希望程序应该计算单词的数量并相应地分配内存.

Now I want that that program should dynamically allocate the memory for the number of words it counts. For example, a .txt file may contain words greater that 1000. Now I want that the program should count the number of words and allocate the memory accordingly.

由于我们不能使用变量代替 [1000],我对如何实现我的逻辑完全一无所知.请在这方面帮助我.

Since we cannot use a variable in place of [1000], I am completely blank at how to implement my logic. Please help me in this regard.

推荐答案

您使用指针.

具体来说,您使用指向地址的指针,并使用标准的 c 库函数调用,您要求操作系统扩展堆以允许您存储您需要的内容.

Specifically, you use a pointer to an address, and using a standard c library function calls, you ask the operating system to expand the heap to allow you to store what you need to.

现在,它可能会拒绝,您需要处理.

Now, it might refuse, which you will need to handle.

下一个问题变成了 - 你如何要求一个二维数组?好吧,你要求一个指针数组,然后展开每个指针.

The next question becomes - how do you ask for a 2D array? Well, you ask for an array of pointers, and then expand each pointer.

举个例子,考虑一下:

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] 可以具有不同的大小,可在运行时确定,就像单词的数量一样.

This gets you a two-dimensional array, where each element words[i] can have a different size, determinable at run time, just as the number of words is.

当您完成数组时,您需要通过循环遍历数组来free()所有结果内存:

You will need to free() all of the resultant memory by looping over the array when you're done with it:

for ( i = 0; i < num_words; i++ )
{
    free(words[i]);
}

free(words);

如果不这样做,就会造成内存泄漏.

If you don't, you'll create a memory leak.

您也可以使用 calloc.区别在于调用约定和效果 - calloc 将所有内存初始化为 0malloc 不会.

You could also use calloc. The difference is in calling convention and effect - calloc initialises all the memory to 0 whereas malloc does not.

如果您需要在运行时调整大小,请使用 realloc.

If you need to resize at runtime, use realloc.

另外,重要的是,注意我使用过的 word_size+1.C 中的字符串以零结尾,这需要考虑一个额外的字符.为了确保我记住这一点,我通常将变量 word_size 的大小设置为单词的大小(我期望的字符串长度),并在 malloc 中明确保留 +1对于零.然后我知道分配的缓冲区可以接受一串 word_size 字符.不这样做也很好 - 我只是这样做是因为我喜欢以一种明显的方式明确说明零.

Also, important, watch out for the word_size+1 that I have used. Strings in C are zero-terminated and this takes an extra character which you need to account for. To ensure I remember this, I usually set the size of the variable word_size to whatever the size of the word should be (the length of the string as I expect) and explicitly leave the +1 in the malloc for the zero. Then I know that the allocated buffer can take a string of word_size characters. Not doing this is also fine - I just do it because I like to explicitly account for the zero in an obvious way.

这种方法也有一个缺点 - 我最近明确地将此视为一个已发布的错误.注意我写的是 (word_size+1)*sizeof(type) - 然而想象一下我写的是 word_size*sizeof(type)+1.对于 sizeof(type)=1 这些是相同的,但 Windows 使用 wchar_t 非常频繁 - 在这种情况下,您将为最后一个零保留一个字节而不是两个- 它们是 type 类型的零终止元素,而不是单个零字节.这意味着您将在读写上超支. 

There is also a downside to this approach - I've explicitly seen this as a shipped bug recently. Notice I wrote (word_size+1)*sizeof(type) - imagine however that I had written word_size*sizeof(type)+1. For sizeof(type)=1 these are the same thing but Windows uses wchar_t very frequently - and in this case you'll reserve one byte for your last zero rather than two - and they are zero-terminated elements of type type, not single zero bytes. This means you'll overrun on read and write.  

附录:以您喜欢的方式进行操作,如果您要将缓冲区传递给依赖它们的东西,请注意那些零终止符.

Addendum: do it whichever way you like, just watch out for those zero terminators if you're going to pass the buffer to something that relies on them.

这篇关于对数组使用动态内存分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆