I am following the book \"C Primer Plus\" and encounter a problem to understand the regions of memory. In the book, it states:
Typically, a p
The C standard states that an object can have one of 4 different storage durations. These are:
The code above addresses the first 3 of these.
A static object is is declared either at file scope or at local scope with the static
modifier. String literals are also static objects.
An automatic object, typically referred to as a local variable, it declared within a function or an enclosing scope.
An allocated object is one whose memory is returned by an allocation function such as malloc
.
In practice, compilers will typically place each of these object types in a different area of memory. Static objects are typically placed in the data section of an executable, automatic (read: local) objects are typically stored on the stack, and allocated objects are typically stored on the heap.
String literals in particular are static objects, and are typically placed in a special part of the data section marked read-only.
These regions are typically in different distinct regions of memory, however they are not required to be. So while in practice the addresses of objects in each of these regions will be noticeably different, they aren't required to be.
So you don't really need to "assure" that different types of variables are in different regions. The compiler takes care of that for you depending on how you define them.
I want to try and explain this in a more simple way.
0x...
is a hexadecimal string that represents a string of binary bits. You can think of it as representing a number, but shorthand because you don't need to know the number, just it's relative value to other similarly coded numbers. So this means that the "address value" is actually just a number.
Why use numbers to represent memory locations? Because for all intents and purposes, memory is just a really large byte array, who's values can be read by index. C logically (not physically) divides this memory array into different sections for efficient storage. So the closer 2 address locations are in memory, the closer they are together in that byte array representation.
The address range available to any application is determined at runtime, and is not actually any part of specific memory spaces. So in all fairness, there is no why to know for sure that certain items are in a certain memory region. Just that it is highly statistically implausible for 2 objects close together in memory to be in different regions.
What might help a bit to get the actual sections allocated for the program is the nm command, there you could e.g. see the static_store offset.
static_store: 30 at 0x600b00
==> 0000000000600b00 D static_store
See it live on coliru: http://coliru.stacked-crooked.com/a/1b45e01f508ec7b7
Note the attached nm command:
gcc main.cpp && ./a.out && nm a.out
However, you have to keep in mind that you're typically on a system with MMU thus having virtual memory addresses mapped to real memory.
Find more infos e.g. on https://www.embeddedrelated.com/showarticle/900.php
Different regions have very different addresses. If they were in the same region, they would have similar addresses. Better example, where we allocate 2 objects in each region:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
int stack1;
int stack2;
static int bss1;
static int bss2;
static int data1=1;
static int data2=1;
int* heap1 = malloc(1);
int* heap2 = malloc(1);
char* rodata1 = "hello";
char* rodata2 = "world";
printf(".stack\t%p %p\n", &stack1, &stack2);
printf(".bss\t%p %p\n", &bss1, &bss2);
printf(".data\t%p %p\n", &data1, &data2);
printf(".heap\t%p %p\n", heap1, heap2);
printf(".rodata\t%p %p\n", rodata1, rodata2);
free(heap1);
free(heap2);
}
Output (for example):
.stack 000000000022FE2C 000000000022FE28
.bss 0000000000407030 0000000000407034
.data 0000000000403010 0000000000403014
.heap 0000000000477C50 0000000000477C70
.rodata 0000000000404000 0000000000404006
As you can see the two variables in the same segment have nearly identical addresses, the only difference being the size of the objects (and possibly some room for alignment). While they have very different addresses compared to variables in the other segments.