views:

135

answers:

5

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:
http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap/79936#79936

+4  A: 

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.

Ned Batchelder
On the other hand, you don't want to put too much on stack, because it is not as big as heap. So, `int data[10]` is just fine, but I wouldn't count on `int data[10000]` working at all.
zvonimir
+4  A: 

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.

Mark H
+1 for mentioning size limitations of the stack, but I think 16 bytes is a bit low. Isn't the default stack size on most platforms in the megabytes (so multi-KB variables should be fine in most cases)?
Brendan Long
Yes, but when you allocate on the stack, you should also consider the lifetime of the data aswell as it's size. I meant 16 bytes for values whose lifetimes may not be known. You might allocate several kb on the stack, then branch off into another function, which also allocates many kb, and so on - it can quickly fill up. (Discussed this more in StackedCrooked's response.)
Mark H
Since the question is about C++, I strongly oppose the recommendation to use malloc. In C, use malloc. In C++, use new.
William Pursell
-1: malloc is evil in C++.
rubenvb
+5  A: 

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.

seattlecpp
+1 for new vs malloc
bstpierre
I don't know if what im doing is correct - but it stems from the docs for PQescapeStringConn -"'to' shall point to a buffer that is able to hold at least one more byte than twice the value of length"from here:http://www.postgresql.org/docs/7.3/static/libpq-exec.html
Gush
+1  A: 

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.
StackedCrooked
I think those general rules are a bit weak. For example, I might allocate 10% of my stack in main(), and then call some other function (which in turn will call more and more, each filling up the stack). I'm not going to be able to free up that space until all my deeper functions are completed (essentially the end of the program in this case). My program has automatically got 10% less stack space. I think that 10% rule should be restricted to **pure** functions only.
Mark H
@Mark H: You're right that the 10% rule should not be allocated in main, and certainly not in reentrant code. However, I don't see how pure functions would be any safer against stack overflow than non-pure functions.
StackedCrooked
A pure function will not call other functions (unless they themselves are pure) - but they will generally perform some algorithm and return immediately. Any local variables you allocate in them will be short-lived, which is how the stack should be. Variables which have longer lifetimes (as previous example) should go on the heap.
Mark H
As long as the pure function is not recursive that is :)
StackedCrooked
+1  A: 

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'.

from http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.htmlVariable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C90 mode and in C++. I guess that's why it compiles and works for me using gcc. I could believe that it's not C++ by the standard or the proper definition of the the language that you could be referring to. Should I remove the C++ tag?
Gush
I was merely wondering which you were using, but for me to assume C++, I thought I'd warn you that VLA's are not part of standard C++.
ok. i did not know that and it is relevant
Gush