Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
262 views
in Technique[技术] by (71.8m points)

c - Using Dynamic Memory allocation for arrays

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

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:

Code:

char words[1000][15];

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

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.

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You use pointers.

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.

As an example, consider this:

int i = 0;
char** words;
words = malloc((num_words)*sizeof(char*));

if ( words == NULL )
{
    /* we have a problem */
    printf("Error: out of memory.
");
    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 */
}

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.

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.

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

If you need to resize at runtime, use realloc.


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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...