Home > Software design >  Dynamic allocation with malloc
Dynamic allocation with malloc

Time:11-19

In what ways is

int main(int argc, char **argv)
{
    int N = atoi(argv[1]);
    int v[N]; 

    ...some code here...
} 

better than

int main(int argc, char **argv)
{
    int count = atoi(argv[1]);
    int *N = malloc(count * sizeof(int));
     ...some code here...

     free(N);
}

?

Is it less error-prone?

P.S: I know where the two will typically be allocated.

Edit: Initialized count.

CodePudding user response:

It's not "better" per se. It does a different thing:

    int v[count];

is a variable-length array in C99 and later. That means it has a lifetime: The moment it goes out of scope (the function in which it was created is finished), it's forgotten.

    int *N = malloc(count * sizeof(int));

on the other hand allocates that memory on the heap. That means it lives as long as you do not explicitly free it (or the program ends, which is at the end of your main, anyway, so this might not be the best code to illustrate the difference on)!

Now, having to remember that you have allocated some memory that you need to deallocate later is a hassle. Programmers get that wrong all the time, and that leads to either memory leaks (you forgetting to free memory you're not using anymore, leading to the memory used by a program growing over time) or use-after-free bugs (you using memory after you've already freed it, which has undefined results and can lead to serious bugs, including security problems).

On the other hand, your stack space is small. Like 4 kB or 8 kB. Try passing 1048576 to your program as argv[1]! That's a meager 1 million ints you're creating. And that probably means you're allocating 4 MB of RAM. 4 MB, compared to the Gigabytes of RAM your computer most likely has, that's simply not much data, right?

But your int v[1048576] would plainly fail, because that's more than a function is allowed to have "scratchpad" space for itself. So, in general, for variable-length things where you cannot know before that they are really small, your second solution with malloc is "better", because it actually works.

General remark: Memory management in C is hard. That's why languages (C and others) have come up with solutions where you can have something that can be made aware of its own lifetime, so that you cannot forget to delete something, because the object itself knows when it is no longer used.

  • Related