Where in memory are my variables stored in C?

281,820

Solution 1

You got some of these right, but whoever wrote the questions tricked you on at least one question:

  • global variables -------> data (correct)
  • static variables -------> data (correct)
  • constant data types -----> code and/or data. Consider string literals for a situation when a constant itself would be stored in the data segment, and references to it would be embedded in the code
  • local variables(declared and defined in functions) --------> stack (correct)
  • variables declared and defined in main function -----> heap also stack (the teacher was trying to trick you)
  • pointers(ex: char *arr, int *arr) -------> heap data or stack, depending on the context. C lets you declare a global or a static pointer, in which case the pointer itself would end up in the data segment.
  • dynamically allocated space(using malloc, calloc, realloc) --------> stack heap

It is worth mentioning that "stack" is officially called "automatic storage class".

Solution 2

For those future visitors who may be interested in knowing about those memory segments, I am writing important points about 5 memory segments in C:

Some heads up:

  1. Whenever a C program is executed some memory is allocated in the RAM for the program execution. This memory is used for storing the frequently executed code (binary data), program variables, etc. The below memory segments talks about the same:
  2. Typically there are three types of variables:
    • Local variables (also called as automatic variables in C)
    • Global variables
    • Static variables
    • You can have global static or local static variables, but the above three are the parent types.

5 Memory Segments in C:

1. Code Segment

  • The code segment, also referred as the text segment, is the area of memory which contains the frequently executed code.
  • The code segment is often read-only to avoid risk of getting overridden by programming bugs like buffer-overflow, etc.
  • The code segment does not contain program variables like local variable (also called as automatic variables in C), global variables, etc.
  • Based on the C implementation, the code segment can also contain read-only string literals. For example, when you do printf("Hello, world") then string "Hello, world" gets created in the code/text segment. You can verify this using size command in Linux OS.
  • Further reading

Data Segment

The data segment is divided in the below two parts and typically lies below the heap area or in some implementations above the stack, but the data segment never lies between the heap and stack area.

2. Uninitialized data segment

  • This segment is also known as bss.
  • This is the portion of memory which contains:
    1. Uninitialized global variables (including pointer variables)
    2. Uninitialized constant global variables.
    3. Uninitialized local static variables.
  • Any global or static local variable which is not initialized will be stored in the uninitialized data segment
  • For example: global variable int globalVar; or static local variable static int localStatic; will be stored in the uninitialized data segment.
  • If you declare a global variable and initialize it as 0 or NULL then still it would go to uninitialized data segment or bss.
  • Further reading

3. Initialized data segment

  • This segment stores:
    1. Initialized global variables (including pointer variables)
    2. Initialized constant global variables.
    3. Initialized local static variables.
  • For example: global variable int globalVar = 1; or static local variable static int localStatic = 1; will be stored in initialized data segment.
  • This segment can be further classified into initialized read-only area and initialized read-write area. Initialized constant global variables will go in the initialized read-only area while variables whose values can be modified at runtime will go in the initialized read-write area.
  • The size of this segment is determined by the size of the values in the program's source code, and does not change at run time.
  • Further reading

4. Stack Segment

  • Stack segment is used to store variables which are created inside functions (function could be main function or user-defined function), variable like
    1. Local variables of the function (including pointer variables)
    2. Arguments passed to function
    3. Return address
  • Variables stored in the stack will be removed as soon as the function execution finishes.
  • Further reading

5. Heap Segment

  • This segment is to support dynamic memory allocation. If the programmer wants to allocate some memory dynamically then in C it is done using the malloc, calloc, or realloc methods.
  • For example, when int* prt = malloc(sizeof(int) * 2) then eight bytes will be allocated in heap and memory address of that location will be returned and stored in ptr variable. The ptr variable will be on either the stack or data segment depending on the way it is declared/used.
  • Further reading

Solution 3

Corrected your wrong sentences

constant data types ----->  code //wrong

local constant variables -----> stack

initialized global constant variable -----> data segment

uninitialized global constant variable -----> bss

variables declared and defined in main function  ----->  heap //wrong

variables declared and defined in main function -----> stack

pointers(ex:char *arr,int *arr) ------->  heap //wrong

dynamically allocated space(using malloc,calloc) --------> stack //wrong

pointers(ex:char *arr,int *arr) -------> size of that pointer variable will be in stack.

Consider that you are allocating memory of n bytes (using malloc or calloc) dynamically and then making pointer variable to point it. Now that n bytes of memory are in heap and the pointer variable requries 4 bytes (if 64 bit machine 8 bytes) which will be in stack to store the starting pointer of the n bytes of memory chunk.

Note : Pointer variables can point the memory of any segment.

int x = 10;
void func()
{
int a = 0;
int *p = &a: //Now its pointing the memory of stack
int *p2 = &x; //Now its pointing the memory of data segment
chat *name = "ashok" //Now its pointing the constant string literal 
                     //which is actually present in text segment.
char *name2 = malloc(10); //Now its pointing memory in heap
...
}

dynamically allocated space(using malloc,calloc) --------> heap

Solution 4

A popular desktop architecture divides a process's virtual memory in several segments:

  • Text segment: contains the executable code. The instruction pointer takes values in this range.

  • Data segment: contains global variables (i.e. objects with static linkage). Subdivided in read-only data (such as string constants) and uninitialized data ("BSS").

  • Stack segment: contains the dynamic memory for the program, i.e. the free store ("heap") and the local stack frames for all the threads. Traditionally the C stack and C heap used to grow into the stack segment from opposite ends, but I believe that practice has been abandoned because it is too unsafe.

A C program typically puts objects with static storage duration into the data segment, dynamically allocated objects on the free store, and automatic objects on the call stack of the thread in which it lives.

On other platforms, such as old x86 real mode or on embedded devices, things can obviously be radically different.

Solution 5

I am referring to these variables only from the C perspective.

From the perspective of the C language, all that matters is extent, scope, linkage, and access; exactly how items are mapped to different memory segments is up to the individual implementation, and that will vary. The language standard doesn't talk about memory segments at all. Most modern architectures act mostly the same way; block-scope variables and function arguments will be allocated from the stack, file-scope and static variables will be allocated from a data or code segment, dynamic memory will be allocated from a heap, some constant data will be stored in read-only segments, etc.

Share:
281,820

Related videos on Youtube

starkk92
Author by

starkk92

Updated on May 04, 2020

Comments

  • starkk92
    starkk92 about 4 years

    By considering that the memory is divided into four segments: data, heap, stack, and code, where do global variables, static variables, constant data types, local variables (defined and declared in functions), variables (in main function), pointers, and dynamically allocated space (using malloc and calloc) get stored in memory?

    I think they would be allocated as follows:

    • Global variables -------> data
    • Static variables -------> data
    • Constant data types -----> code
    • Local variables (declared and defined in functions) --------> stack
    • Variables declared and defined in main function -----> heap
    • Pointers (for example, char *arr, int *arr) -------> heap
    • Dynamically allocated space (using malloc and calloc) --------> stack

    I am referring to these variables only from the C perspective.

    Please correct me if I am wrong as I am new to C.

    • simonc
      simonc over 11 years
      main is just another function. Variables go on the stack unless malloc'd just like elsewhere.
    • m0skit0
      m0skit0 over 11 years
      Is this actually defined by C standard? I think this is more architecture dependent.
    • Montre
      Montre over 11 years
      Most of the fine details are probably implementation-dependent. (I.e. there's nothing that forbids a C compiler/runtime that heap-allocates everything including "stack frames".)
    • Ciro Santilli OurBigBook.com
      Ciro Santilli OurBigBook.com about 9 years
    • VimNing
      VimNing over 3 years
      Note for myself: Read @Kerrek SB's answer.
  • simonc
    simonc over 11 years
    The statements about main and dynamically allocated variables are wrong too
  • argentage
    argentage over 11 years
    pointers can be in either the stack or the heap (see especially: pointers to pointers)
  • rashok
    rashok over 11 years
    @airza : Now updated. ACtually I was updating that details only :)
  • Steve Jessop
    Steve Jessop over 11 years
    Also worth mentioning that the heap officially isn't called anything at all. Allocated memory comes from somewhere, there is no name in the standard for that "somewhere".
  • Steve Jessop
    Steve Jessop over 11 years
    "I believe that practice has been abandoned because it is too unsafe" - and makes it impossible to implement threads, since then you need more than one stack per program and they can't all be at the end :-)
  • Kerrek SB
    Kerrek SB over 11 years
    @SteveJessop: Yes, I was thinking that too. But threads have existed for a long time -- I don't know if all the thread stacks also grew backwards, or if they'd grow up like the heap... anyway, nowadays everything goes in the same direction and there are guard pages.
  • Andreas Grapentin
    Andreas Grapentin over 11 years
    On some systems, (namely Linux and *BSD) there is also alloca which works similar to malloc, but does stack allocation.
  • mahoriR
    mahoriR about 10 years
    In the following memory map, could you please point out where is stack and heap? I am not sure if this is correct question as stack and memory may be only applicable at run time. MEMORY MAP: "text data bss dec hex filename 7280 1688 1040 10008 2718 a.exe "
  • Sebi2020
    Sebi2020 over 8 years
    Not only on the stack or data segment. Think of an pointer which points to an array of pointers. In this case the pointers in the array are stored on the heap.
  • Suraj Jain
    Suraj Jain almost 8 years
    Shouldn't that be initialized instead of uninitialized in 3. Initialized data segment.
  • Haoyuan Ge
    Haoyuan Ge over 7 years
    What is environmental/command line section? Does they exist in Linux?
  • myradio
    myradio almost 7 years
    I guess you understood what I meant, just to make it clear, I didn't mean to ask where a is stored but rather where the block of memory a is pointing to is.
  • Sergey Kalinichenko
    Sergey Kalinichenko almost 7 years
    @myradio There's no pointer in int a[10] or int a[b] declaration, they declare arrays. These arrays are placed in the automatic memory area.
  • Peter Mortensen
    Peter Mortensen almost 7 years
    Re "stored in the uninitialized data segment" (multiple instances): Do you mean "stored uninitialized in the data segment"?
  • hagrawal
    hagrawal almost 7 years
    @PeterMortensen I mean both things. "Any global or static local variable which is not initialized will be stored in the uninitialized data segment"
  • Admin
    Admin over 6 years
    how can we have global static variable in C ?
  • Admin
    Admin over 6 years
    under "some heads up", I found this point "You can have global static or local static variables, but the above three are the parent types." in which u referred to the term "global static". My point is a static variable cannot be global. i.e., if any variable has to be global then it should be accessible until the program's execution is complete. Please explain and help if I am wrong.
  • Peter Cordes
    Peter Cordes almost 4 years
    Modern GNU binutils ld separates .rodata, putting it in its own read-only non-exec segment, separate from code (I tested on GNU/Linux). This means static constants like string literals are no longer possible candidates for Spectre / ROP gadgets because they're in non-executable pages.
  • Peter Cordes
    Peter Cordes almost 3 years
    initialized global constant variable -----> data segment Nope, this answer is wrong, the question was right about that for older linkers. If the .rodata section isn't linked into the text segment (Read + eXec) along with the code like older linkers did, modern GNU ld defaults to linking it into its own segment which is read only and not executable. If not optimized away entirely, non-zero global const variables certainly don't go in R+W the .data section or get linked into the R+W data segment. You're right that zero-valued ones will go in .bss though.