I am trying to understand how memory is managed in a C program. I know that there are the following segments in memory:
Now consider the following program:
#include <stdio.h>
int main(){
int arr[4] = {1,2,3,4};
int x = 10;
printf("Hello World!");
}
In the above program,both arr and x are locally declared within the main function. I thought that this would mean that they would both be allocated space on the function stack. However, when I ran the size command on linux, I found out that the array is actually being allocated space in the data segment.
I have searched for this online but have found conflicting information. Some answers say that all locally declared variables should go to the stack while others say that the array should go on the heap. I think the array would go to the heap in case I was dynamically allocated memory using malloc, which is not the case here in this example.
An array is stored in contiguous sequential memory locations, with the first element at the lowest address. A linked list is stored in memory as an unordered and noncontiguous set of list elements, each consisting of a data value and a pointer to the next data list element.
Array bucket values are stored in contiguous memory locations (thus pointer arithmetic can be used to iterate over the bucket values), and 2D arrays are allocated in row-major order (i.e. the memory layout is all the values in row 0 first, followed by the values in row1, followed by values in row 2 ...).
Storage of Arrays As discussed, the reference types in Java are stored in heap area. Since arrays are reference types (we can create them using the new keyword) these are also stored in heap area.
When we declare an array, space is reserved in the memory of the computer for the array. The elements of the array are stored in these memory locations. The important thing about arrays is that array elements are always stored in consecutive memory locations.
I have searched for this online but have found conflicting information.
Please do not read random blogs or such, they usually have bad information. On Stack Overflow wrong information tends to be downvoted or at least would usually have comments pointing out the inaccuracies and fallacies.
In the above program, both arr and x are locally declared within the main function. I thought that this would mean that they would both be allocated space on the function stack.
The C standard does not specify how memory for variablesobjects should be allocated. It only specifies that objects have storage durations, which define the lifetime of the variableobject
{ ... }
which contains the declaration (or compound literal), until the end of the blockmalloc/calloc/realloc/aligned_alloc
until corresponding free/realloc
.In addition to that, the C standard specifies that during its lifetime, an object will
&
operator)Now, in addition to that, there is the so-called as-if rule which says that a compiler can produce any program code for as long as the external behaviour of the program is the same, external behaviour meaning input, output, access to volatile objects and so on.
The variables in your program have automatic storage duration, which means every time you enter the main
function you will have new objects with new lifetime until the end of the main
function. Usually this would mean that they would be stored on the stack, because it will nicely handle the allocations and deallocations with minimal overhead. But your program has the same external behaviour as
#include <stdio.h>
int main(void) {
printf("Hello World!");
}
It means that the compiler can completely eliminate these two variables and not reserve any space for it.
Now, if you print address of the variables:
#include <stdio.h>
int main(void) {
int arr[4] = {1,2,3,4};
int x = 10;
printf("Hello World! %p, %p\n", (void *)arr, (void *)&x);
}
because the variables have their addresses taken and used for output, C cannot optimize them out. Are they on stack now? Well, C standard does not say. They need to have lifetime from at least beginning of main
until the end - but the C compiler can decide to not use the stack for them, as the external behaviour of that program would be the same as
#include <stdio.h>
static int arr[4] = {1,2,3,4};
static int x = 10;
int main(void) {
printf("Hello World! %p, %p\n", (void *)arr, (void *)&x);
}
which would put these variables in the static data segment; of course the addresses would be different but again C does not give any guarantees about where the particular objects are located in memory, just that they will have addresses.
However, when I ran the size command on linux, I found out that the array is actually being allocated space in the data segment.
I think you have misunderstood what you have seen.
The C-standard doesn't say anything about this. It only says that arr
has automatic storage duration. However, most (if not all) systems will save both x
and arr
on a stack.
Try this code:
#include<stdio.h>
int main(){
int arr[4] = {1,2,3,4};
int x = 10;
static int i = 0;
printf("Hello World! arr is here %p and x is here %p\n", (void*)arr, (void*)&x);
++i;
if (i < 3) main();
return 0;
}
Possible output:
Hello World! arr is here 0x7ffcdaba4170 and x is here 0x7ffcdaba416c
Hello World! arr is here 0x7ffcdaba4140 and x is here 0x7ffcdaba413c
Hello World! arr is here 0x7ffcdaba4110 and x is here 0x7ffcdaba410c
Even if this isn't a solid proof, it strongly indicates that the system is using a stack and that the stack grows towards lower addresses and that both arr
and x
is stores on that stack.
BTW: Printing the stack-pointer can't be done in a portable way but this is a good read: Print out value of stack pointer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With