2
int numbers*;
numbers = malloc ( sizeof(int) * 10 );

I want to know how is this dynamic memory allocation, if I can store just 10 int items to the memory block ? I could just use the array and store elemets dynamically using index. Why is the above approach better ?

I am new to C, and this is my 2nd day and I may sound stupid, so please bear with me.

7 Answers 7

4

In this case you could replace 10 with a variable that is assigned at run time. That way you can decide how much memory space you need. But with arrays, you have to specify an integer constant during declaration. So you cannot decide whether the user would actually need as many locations as was declared, or even worse , it might not be enough.

With a dynamic allocation like this, you could assign a larger memory location and copy the contents of the first location to the new one to give the impression that the array has grown as needed.

This helps to ensure optimum memory utilization.

Sign up to request clarification or add additional context in comments.

2 Comments

-1, this is simply not true, modern C allows dynamic allocation on the stack
+1 because Jens' comment is a bit severe. There are a lot of reasons why dynamic allocation on the stack may not be appropriate (stack size limits, scope and lifetime, portability etc.) and not mentioning them in the answer to a beginner is not a error.
4

The main reason why malloc() is useful is not because the size of the array can be determined at runtime - modern versions of C allow that with normal arrays too. There are two reasons:

  • Objects allocated with malloc() have flexible lifetimes;

That is, you get runtime control over when to create the object, and when to destroy it. The array allocated with malloc() exists from the time of the malloc() call until the corresponding free() call; in contrast, declared arrays either exist until the function they're declared in exits, or until the program finishes.

  • malloc() reports failure, allowing the program to handle it in a graceful way.

On a failure to allocate the requested memory, malloc() can return NULL, which allows your program to detect and handle the condition. There is no such mechanism for declared arrays - on a failure to allocate sufficient space, either the program crashes at runtime, or fails to load altogether.

Comments

3

There is a difference with where the memory is allocated. Using the array syntax, the memory is allocated on the stack (assuming you are in a function), while malloc'ed arrays/bytes are allocated on the heap.

/* Allocates 4*1000 bytes on the stack (which might be a bit much depending on your system) */
int a[1000];

/* Allocates 4*1000 bytes on the heap */
int *b = malloc(1000 * sizeof(int))

Stack allocations are fast - and often preferred when:

  • "Small" amount of memory is required
  • Pointer to the array is not to be returned from the function

Heap allocations are slower, but has the advantages:

  • Available heap memory is (normally) >> than available stack memory
  • You can freely pass the pointer to the allocated bytes around, e.g. returning it from a function -- just remember to free it at some point.

A third option is to use statically initialized arrays if you have some common task, that always requires an array of some max size. Given you can spare the memory statically consumed by the array, you avoid the hit for heap memory allocation, gain the flexibility to pass the pointer around, and avoid having to keep track of ownership of the pointer to ensure the memory is freed.

Edit: If you are using C99 (default with the gnu c compiler i think?), you can do variable-length stack arrays like

int a = 4;
int b[a*a];

Comments

2

In the example you gave

int *numbers;
numbers = malloc ( sizeof(int) * 10 );

there are no explicit benefits. Though, imagine 10 is a value that changes at runtime (e.g. user input), and that you need to return this array from a function. E.g.

int *aFunction(size_t howMany, ...)
{
    int *r = malloc(sizeof(int)*howMany);
    // do something, fill the array...
    return r;
}

The malloc takes room from the heap, while something like

int *aFunction(size_t howMany, ...)
{
    int r[howMany];
    // do something, fill the array...
    // you can't return r unless you make it static, but this is in general
    // not good
    return somethingElse;
}

would consume the stack that is not so big as the whole heap available.

More complex example exists. E.g. if you have to build a binary tree that grows according to some computation done at runtime, you basically have no other choices but to use dynamic memory allocation.

Comments

1

Array size is defined at compilation time whereas dynamic allocation is done at run time.

Thus, in your case, you can use your pointer as an array : numbers[5] is valid.

If you don't know the size of your array when writing the program, using runtime allocation is not a choice. Otherwise, you're free to use an array, it might be simpler (less risk to forget to free memory for example)

Example:

  • to store a 3-D position, you might want to use an array as it's alwaays 3 coordinates
  • to create a sieve to calculate prime numbers, you might want to use a parameter to give the max value and thus use dynamic allocation to create the memory area

Comments

1

Array is used to allocate memory statically and in one go. To allocate memory dynamically malloc is required.

e.g. int numbers[10];

This will allocate memory statically and it will be contiguous memory.

If you are not aware of the count of the numbers then use variable like count.

int count;
int *numbers;
scanf("%d", count);
numbers = malloc ( sizeof(int) * count );

This is not possible in case of arrays.

Comments

0

Dynamic does not refer to the access. Dynamic is the size of malloc. If you just use a constant number, e.g. like 10 in your example, it is nothing better than an array. The advantage is when you dont know in advance how big it must be, e.g. because the user can enter at runtime the size. Then you can allocate with a variable, e.g. like malloc(sizeof(int) * userEnteredNumber). This is not possible with array, as you have to know there at compile time the (maximum) size.

3 Comments

1. Then please entlight me/us what the correct answer is. 2. If you refer to vla - that exist only since C99 and has many limitations compared to usual dynamic arrays/pointers.
I do indeed refer to VLA, your final phrase is just plain wrong. There are other answers to this question that handle this subject quite satisfactory. C99 is the actual standard for C, for 12 years now. If you are just willing to talk about historic C, AKA C89, say so in your answer.
C99 is not really the standard - the number of compilers supporting C99 complete is very limited. E.g. gcc approx. 15% of C99 features are missing. Other post already told of the limitations (e.g. lifetime, nasty sideeffect like vla deallocation deallocates also alloca allocated memory). Original poster stated he is a beginner, so I answered in the context of what usually is referred to when talking about "dynamic memory vs array".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.