Gush
Gush

Reputation: 319

c++: local array definition versus a malloc call

What is the difference between this:

somefunction() {  
    ...  
    char *output;   
    output = (char *) malloc((len * 2) + 1);  
    ...  
}  

and this:

somefunction() {  
    ...  
    char output[(len * 2) + 1];  
    ...  
}  

When is one more appropriate than the other?

thanks all for your answers. here is a summary:

  1. ex. 1 is heap allocation
  2. ex. 2 is stack allocation
  3. there is a size limitation on the stack, use it for smaller allocations
  4. you have to free heap allocation, or it will leak
  5. the stack allocation is not accessible once the function exits
  6. the heap allocation is accessible until you free it (or the app ends)
  7. VLA's are not part of standard C++

corrections welcome.

here is some explanation of the difference between heap vs stack:
What and where are the stack and heap?

Upvotes: 7

Views: 8099

Answers (5)

jA_cOp
jA_cOp

Reputation: 3305

You tagged your question with both C++ and C, but the second solution is not allowed in C++. Variable length arrays are only allowed in C(99).

If you were to assume 'len' is a constant, both will work.

malloc() (and C++'s 'new') allocate the memory on the heap, which means you have to free() (or if you allocated with 'new', 'delete') the buffer, or the memory will never be reclaimed (leak).

The latter allocates the array on the stack, and will be gone when it goes out of scope. This means that you can't return pointers to the buffer outside the scope it's allocated in.

The former is useful when you want to pass the block of memory around (but in C++, it's best managed with an RAII class, not manually), while the latter is best for small, fixed-size arrays that only need to exist in one scope.

Lastly, you can mark the otherwise stack-allocated array with 'static' to take it off the stack and into a global data section:

static char output[(len * 2) + 1];

This enables you to return pointers to the buffer outside of its scope, however, all calls to such a function will refer to the same piece of global data, so don't use it if you need a unique block of memory every time.

Lastly, don't use malloc in C++ unless you have a really good reason (i.e, realloc). Use 'new' instead, and the accompanying 'delete'.

Upvotes: 2

StackedCrooked
StackedCrooked

Reputation: 35485

First some terminology:

  • The first sample is called heap allocation.
  • The second sample is called stack allocation.

The general rule is: allocate on the stack, unless:

  1. The required size of the array is unknown at compile time.
  2. The required size exceeds 10% of the total stack size. The default stack size on Windows and Linux is usually 1 or 2 MB. So your local array should not exceed 100,000 bytes.

Upvotes: 3

seattlecpp
seattlecpp

Reputation: 187

The first example allocates a block of storage from the heap. The second one allocates storage from the stack. The difference becomes visible when you return output from somefunction(). The dynamically allocated storage is still available for your use, but the stack-based storage in the second example is, um, nowhere. You can still write into this storage and read it for awhile, until the next time you call a function, at which time the storage will get overwritten randomly with return addresses, arguments, and such.

There's a lot of other weird stuff going on with the code in this question too. First off, it this is a c++ program, you'd want to use new instead of malloc() so you'd say

output = new char[len+1];

And what's with the len*2 + 1 anyway? Maybe this is something special in your code, but I'm guessing you want to allocate unicode characters or multibyte characters. If it's unicode, the null termination takes two bytes as well as each character does, and char is the wrong type, being 8 bit bytes in most compilers. If it's multibyte, then hey, all bets are off.

Upvotes: 5

Mark H
Mark H

Reputation: 13897

Use locals when you only have a small amount of data, and you are not going to use the data outside the scope of the function you've declared it in. If you're going to pass the data around, use malloc.

Local variables are held on the stack, which is much more size limited than the heap, where arrays allocated with malloc go. I usually go for anything > 16 bytes being put on the heap, but you have a bit more flexibility than that. Just don't be allocating locals in the kb/mb size range - they belong on the heap.

Upvotes: 6

Ned Batchelder
Ned Batchelder

Reputation: 375584

The first allocates memory on the heap. You have to remember to free the memory, or it will leak. This is appropriate if the memory needs to used outside the function, or if you need to allocate a huge amount of memory.

The second allocates memory on the stack. It will be reclaimed automatically when the function returns. This is the most convenient if you don't need to return the memory to your caller.

Upvotes: 9

Related Questions