Hello guys, sorry to disturb you all; can someone explain what is the difference between stack and heap memory please. My main concern is about how stack and heap affect static and dynamic arrays. For static array, I know we allocate constant memory which cannot change, right? But for dynamic arrays, what happen? We also allocate memory but how come the memory can change?
#Static Array Vs Dynamic Array and Stack Vs Heap memory
1 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.
What I want to know, in C, say we created an array of size 5, we didn't use malloc, so memory is allocated on the stack and not on heap?
Since memory is allocated on heap, we can't copy the array to another memory location with greater size? Like if I want size of 10 now?
Why the heap allows us to "copy" a chunk of memory, then allocate that chunk to a bigger chunk of memory
- yes. Since the compiler knows the size at compile time it instructs the OS to 'reserve' some stack memory for it
- sure you can.
memcpyexists - the memory itself care less about whatever stored in it. Its you allocator responsibility to give you some large enough block to place stuff in and reallocate another block if you (the programmer) asked it to do so and copy the content over
You use heap as opposed to a stack when you need a fine-grained control of how long the memory should exist. E.g. if it should outlive the current function, it must be on the heap
Also if the array size is computed at runtime (as opposed to known at compile-time) heap is usually preferred, because stack arrays are required to have their size known at compile-time in C++ and in some C compilers (namely MSVC)
Stack arrays of size that's not known at compile-time are called VLAs (variable-length arrays):
What Is a VLA, and Why Is It "Bad"?
A Variable Length Array (VLA) is an array where the size is not constant and depends on a variable.
Example
int size = rand();
int vla[size]; // VLA of type int[size]
int not_vla[10]; // regular array of type int[10]
constexpr int size = 10;
int arr[size]; // also not a VLA, of type int[10]
Why Are VLAs "Bad"?
VLAs have poor compiler support and can lead to unsafe code. The core issue with VLAs is that the compiler doesn't know the size of the stack frame. Without warning flags like -Wvla, it can be easy to create a VLA by accident, even in C++ with some compilers.
Compiler Support
:white_check_mark: available since C99
:no_entry: not available in C++ at all
:no_entry: was never supported by MSVC
:warning: optional feature since C11
:warning: supported as non-standard extension by GCC and clang
I know we allocate constant memory which cannot change, right? But for dynamic arrays, what happen? We also allocate memory but how come the memory can change?
Whether the "memory can change" is unrelated to stack vs heap
Constants that can't be modified reside in neither stack nor heap (e.g. "foo"[1] = 'a' is illegal, it crashes in C and doesn't compile in C++)
If you mean "array size can change" rather than "memory can change", then once the array is created, its size can't be changed for neither stack nor heap arrays. Or if you mean "array size doesn't have to be fixed at compile-time", then see above
I mean, say I created an array of know size, say size 5 at compile time, so something like char word = {'H','i'}
Size of the array is 2, right?
Is it possible to make the size becomes greater at run-time? Like increase size from say 2 to 5 if we are using a stack ?
The thing is whatever is allocated some memory location. Similarly, the heap also allocates some memory location. Now, can we modify the number of memory allocated on the stack? I know on the heap, we can use realloc to reallocate greater memory
This isn't a legal syntax. You could do char word[] = "Hi"; or char word[] = {'H','i'}; (Note that the two are not equivalent, the former is equivalent to char word[] = {'H','i','\0'};
Is it possible to make the size becomes greater at run-time? Like increase size from say 2 to 5 if we are using a stack ?
No. As I said:
If you mean "array size can change" rather than "memory can change", then once the array is created, its size can't be changed for neither stack nor heap arrays.
Realloc creates a new array for you and copies over the elements, then destroys the old one. (I think it can sometimes grow in place, without moving the elements? Not sure.)
oh yeah true, sorry I'm not yet used to the syntax, thanks to pin point that these 2 are different, "Hi" contains the termination character \0 while the other doesn't? Is there a difference when we use them in code? Like one better than the other ? Any use case ?
You almost always want to have the null terminator. Most standard functions that accept strings need it
ah I see, like even on the heap, we don't "add things to the array" but a new array is completely created
Depends on the block the allocator handed over (and the impl ofc). Technically it can if said block is large enough
ahh ok, like to know where the string ends ?
Ok, so just to sum up guys:
Arrays can't grow, well if we need it to grow, we must first destroy the array, creates another one and allocate bigger memory to it.
Now, can we destroy a particular array and reallocate memory to it if it's found on the stack? No we can't, the compiler knows that we would be requirement an exact amount of memory for that and won't allow us to reallocate memory (please confirm this statement). In contrast, with the heap, we can reallocate memory by creating a new array.
Thing to pinpoint:
Array CAN'T grow by themselves, like we can't expect a particular memory location to grow, instead, we reallocate the memory location
@rose plinth Has your question been resolved? If so, type !solved :)
- As already mentioned 'arrays' i.e.
T name[]must have a fixed size - they cannot be 'destroyed' on demand either. They have automatic storage duration (the compiler will generate the correct code to 'destroy' them when their scope end)
- memory blocks obtained from some allocator may be 'destroyed' (returned back to the allocator)
- they also may 'grow' (depends on the allocator)
Assuming you're talking about malloc and friends (i.e. the libc allocator)
- blocks obtained from the allocator may be returned back (destroyed)
- blocks may 'grow'. The 'growth' (
realloc) may or may not happen 'in place' (the same block will 'suddenly' become 'bigger', or a new block will be obtained and the old content will be copied over)
Arrays of size which is unknown at compile time, can either be created using VLAs (again already mentioned by BlackCat) or with alloca (not standard)
hmm what do you mean by the array cannot have a fixed size please; like if we say T name[5]; compiler won't assign sufficient memory enough to allocate 5 items ?
Typo, sorry. 'Must'
yeah I see
yep it's clear now, I believed my doubts have been cleared, thanks !! will come back if I have other questions
!solved