C Array Instantiation - Stack or Heap Allocation?
Asked Answered
K

2

31

I guarantee that this question has been asked before, but I haven't been able to find it via search; sorry in advance for any redundancies.

It's my (potentially wrong) understanding that you only allocate to the stack when you know the size of an object at compile time. So in the case of initializing an array, you could do one of these (and this should go on the stack):

char charArray[50];

Since the size of this array is known at compile time, this should have no issues.

On the other hand, this (I believe) is also valid code:

char anotherCharArray[someVariable + 50];

Would this go on the stack as well? I am pretty sure the code segfaults if you free() this, so it makes me think it does, but it doesn't really make sense to me. Similarly, is the 100% sole situation where you have to use free() when the data was allocated via malloc?

Thanks in advance for your help.

Kilocycle answered 13/10, 2012 at 15:36 Comment(3)
@Shookit: you need to specify whether you're talking about local variables or globals.Eggshaped
@PaulR if the array is variable-length, it can't be in the global scope.Lumen
You have to distinguish between the automatic storage and the stack, which is a low-level way to store data. Data placed in automatic storage can be placed in other places as well, like in registers. In the case of a local array with an unknown size (known as VLA:s) the compiler can place it on the stack, it is also allowed to allocate the memory on the heap (as long at it release it at appropriate locations). In fact, VLA:s do not go well together with setjmp/longjmp as they might leak (and are allowed to do so by the C standard).Dimerous
L
6

Similarly, is the 100% sole situation where you have to use free() when the data was allocated via malloc?

Yes. (Apart from calloc and realloc, their return value is also to be free()'d. Similarly, there are functions that use malloc() and this fact is documented, for example strdup() - the return value of these functions is also to be freed using free(), obviously.)

char anotherCharArray[someVariable + 50];

Would this go on the stack as well?

Yes, it does (in most implementations - of course, it's not always true that you assume, but on most of the platforms, it is). And yes this is valid code, but it is only standard in C99.

Lumen answered 13/10, 2012 at 15:39 Comment(5)
All right, so it seems like my biggest misconception was assuming that stack memory allocation requires knowledge of size at compile time then? I marked this as answered (but still feel free to answer my comment :)Kilocycle
@Kilocycle Yes, that's a complete misconception; having a known size is irrelevant to where something is allocated. The only connection is that, in previous versions of C, for various historical reasons, auto variables had to have a known size, and only auto variables can be allocated on the stack.Unbind
@JimBalter answered your question very well :)Lumen
Fantastic, and thanks so much for everyone's help. It never made sense to me that it had to be known at compile time, since you'd expect the stack frame to be able to grow as much as it needs to within the memory space (until another function is called and a new stack frame is created).Kilocycle
Even if you know the size at compile time, if that's more than a few megabytes and on the stack, at runtime some C implementations will cause a stack overflow. #27482207 (Ha. First time I've used the site's own name.)Basophil
E
21

If char charArray[50]; is defined at file scope (outside of all functions) or is static, it's not going to be on the stack, it's going to be a global preallocated at program's start variable. If it's not static and is defined at function scope, it's going to be on the stack.

char anotherCharArray[someVariable + 50]; can only be defined at function scope and is going to be on the stack.

All of the above applies to typical implementations of C. Atypical ones may use the heap instead of the stack and instead of the preallocated space in the data section of the program.

You don't free() what hasn't been allocated with malloc(), calloc() or realloc(). Simple. Some functions may imply the use of one of the above, e.g. POSIX strdup().

Ennui answered 13/10, 2012 at 15:43 Comment(2)
If we're in the global scope, char someArray[variableLenght]; is not allowed...Lumen
@H2CO3 Did the most recent edit remove ambiguity? I don't see where I would imply that that is allowed in the global scope.Ennui
L
6

Similarly, is the 100% sole situation where you have to use free() when the data was allocated via malloc?

Yes. (Apart from calloc and realloc, their return value is also to be free()'d. Similarly, there are functions that use malloc() and this fact is documented, for example strdup() - the return value of these functions is also to be freed using free(), obviously.)

char anotherCharArray[someVariable + 50];

Would this go on the stack as well?

Yes, it does (in most implementations - of course, it's not always true that you assume, but on most of the platforms, it is). And yes this is valid code, but it is only standard in C99.

Lumen answered 13/10, 2012 at 15:39 Comment(5)
All right, so it seems like my biggest misconception was assuming that stack memory allocation requires knowledge of size at compile time then? I marked this as answered (but still feel free to answer my comment :)Kilocycle
@Kilocycle Yes, that's a complete misconception; having a known size is irrelevant to where something is allocated. The only connection is that, in previous versions of C, for various historical reasons, auto variables had to have a known size, and only auto variables can be allocated on the stack.Unbind
@JimBalter answered your question very well :)Lumen
Fantastic, and thanks so much for everyone's help. It never made sense to me that it had to be known at compile time, since you'd expect the stack frame to be able to grow as much as it needs to within the memory space (until another function is called and a new stack frame is created).Kilocycle
Even if you know the size at compile time, if that's more than a few megabytes and on the stack, at runtime some C implementations will cause a stack overflow. #27482207 (Ha. First time I've used the site's own name.)Basophil

© 2022 - 2024 — McMap. All rights reserved.