7

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?

Community
  • 1
  • 1
Gush
  • 319
  • 3
  • 11
  • You should consult your C++ book. If you do not have a C++ book, I'd recommend getting one of the beginner texts listed in [The Complete C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – James McNellis Jul 17 '10 at 00:19
  • 4
    Also, the question depends entirely on how `len` is defined; if it is not a constant, then the second code example is ill-formed C++. – James McNellis Jul 17 '10 at 00:23
  • len is an int and assigned to the result of strlen inside the function. – Gush Jul 17 '10 at 00:32
  • 3
    i dont understand folks with their "buy a book" response. Is not every question answered by some book somewhere? Unless your meaning is this question is answered by a multitude of books, which case, are "basic" questions no acceptable at the great stackoverflow? I'm not referring to pointers to specific books like James McNellis, just pointers to books in general like Brian R. Bondy. How about filtering out your searches for questions flagged as basic? Thanks, for the suggestion though. How do you spell C? – Gush Jul 17 '10 at 00:34
  • 2
    @Gush: My recommendation to refer to a good book is a serious recommendation. One cannot learn a language, especially not one as complex as C++, solely by asking questions on the internet. Any intro-level text on C or C++ would cover this sort of topic very early-on as object storage durations are a fundamental part of the language. Questions that are trivially basic, while permitted on SO, are disconcerting because they often indicate that the questioner may be learning the language from a poor source (I'm not saying that is necessarily the case with you, just that it is often the case). – James McNellis Jul 17 '10 at 00:44
  • @Brian: Gush makes a good point; you wouldn't want him buying a Schildt book, would you? ;-) (@Gush: There is a [Definitive C Book Guide and List](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list) that lists some good texts on C). – James McNellis Jul 17 '10 at 00:47
  • @James - If I was not totally clear, I was not referring to recommendations for specific books - as your's was - which, btw, i found helpful and I appreciate your time. – Gush Jul 17 '10 at 01:08
  • @Gush: The exact C book to buy really doesn't matter, every possible one will cover stack vs heap allocations. My recommendation to buy a book is because it's a much better way to learn C compared to asking a series of basic questions. You may be insulted by my recommendation to buy a book but honestly it's the best suggestion you can get. – Brian R. Bondy Jul 17 '10 at 01:10
  • @Gush: Here are some differences: http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap/79936#79936 – Brian R. Bondy Jul 17 '10 at 01:16
  • If you're using C++, just use `std::vector`. – jamesdlin Jul 17 '10 at 03:24

5 Answers5

8

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
  • 364,293
  • 75
  • 561
  • 662
  • 1
    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. – zvone Jul 17 '10 at 01:57
6

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
  • 13,797
  • 4
  • 31
  • 45
  • 2
    +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 Jul 17 '10 at 00:55
  • 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 Jul 17 '10 at 01:05
  • 3
    Since the question is about C++, I strongly oppose the recommendation to use malloc. In C, use malloc. In C++, use new. – William Pursell Jul 17 '10 at 02:09
5

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
  • 177
  • 1
  • 7
  • 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 Jul 17 '10 at 00:48
3

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
  • 34,653
  • 44
  • 154
  • 278
  • 1
    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 Jul 17 '10 at 00:35
  • 1
    @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 Jul 17 '10 at 00:43
  • 1
    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 Jul 17 '10 at 00:49
  • 2
    As long as the pure function is not recursive that is :) – StackedCrooked Jul 17 '10 at 00:49
2

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

jA_cOp
  • 3,275
  • 19
  • 15
  • from http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html Variable-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 Jul 17 '10 at 01:00
  • 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++. – jA_cOp Jul 17 '10 at 01:05