Local pointers, `static` pointers and` malloc` pointers

void foo() { char *c1 = "abc"; static char *c2 = "abc"; char *c3 = malloc(10); strcpy(c3, "abc"); } 

In foo , I assume:

c1 is a local pointer, so it must be on the stack;

c2 - static pointer, it must be on the heap;

c3 is on the heap.

According to my assumption, I am drawing a graph about pointers and string literals that they indicate,

  stack rodata heap | | | | | | | c1 |------>| "abc" |<--------| c2 | | .. | | | \ | .. | | | | | `------| c3 | | | | | | | 

My guess and schedule are right?

However, I do not quite understand why c3 should be on the heap? c3 is just a char * , just pointing to the address (located on the heap) doesn't c3 on the heap, right?

+6
source share
6 answers

Your guess is wrong. c3 does not point to the literal "abc" . It points to the memory returned by malloc that you will copy.

In addition, c1 and c3 are in automatic storage (on the stack). They are pointers in the field of functions. Objects c3 indicate, however, in dynamic storage (heap), but c3 itself is not.

More correct graph:

  stack rodata heap global | | | | | | | | | c1 |------>| "abc" |<--------------------| c2 | | c3 |------------------------>| "abc" | | | | | | | | | | | | | 
+8
source

The actual variable c3 is on the stack because it is a local variable. However, the data pointed to by c3 will be on the heap because the pointer was created using malloc .

Note that you must free what c3 points out before your function returns, or you have a memory leak in the application, which is never a good idea.

+4
source

c1 and c3 are pointers with automatic storage duration. These 2 pointers live on the stack of your foo () function. That they point to another matter.

c2 is static and lives somewhere else (usually this is not a bunch, but some other section of data that is valid for the entire duration of the program).

Both c1 and c2 point to the string literal "abc". Typically, string literals are placed in a read-only section, and similar strings are concatenated, so c1 and c2 point to the same memory.

c3 points to memory allocated by malloc (), which is memory commonly referred to as heap. Then you copy the string "abc" to this memory on the heap.

+1
source

c1 is a local pointer, so it must be on the stack;

Right. Although it can also be allocated in the CPU register.

c2 - static pointer, it must be on the heap;

Not. A variable declared as static, or a variable declared as global ("file scope"), has something called a static storage duration. This means that before calling the program, they must be initialized to a known value. If the programmer does not explicitly initialize them, the compiler ensures that they are set to zero.

To simplify static initialization, all such objects of static storage duration are usually placed in a separate, allocated part of RAM, often called .bss . It is unlikely that .bss will be pushed onto the stack.

c3 is on the heap.

The actual C3 pointer is on the stack, but the contents it points to are on the heap. The only variables that are on the heap are those that you dynamically allocate using malloc (). Nothing else exists.

My guess and schedule are right?

C1 is correct, the pointer points to the string literal rodata, which is stored in a read-only section in memory.

C2 is invalid because it is in .bss. It points to the string literal rodata, though, as in your graph.

C3 is invalid. When you strcpy () something, you make a hard copy of the string literal in rodata and store that copy on the heap in the area that C3 points to. C3 itself is on the stack.

EDIT: Not sure if this chart is worth it, but here you go.

  stack .bss rodata heap | | | | | | | | | c1 |-------------->| "abc" | | | | | | c2 |--->| "abc" | | | | c3 |----------------------------->|abc | | | | | | | | | 
+1
source

A data segment is part of the virtual address space of a program that contains global variables and static variables that are initialized by the programmer.

In C, objects with a static allocation without an explicit initializer are initialized to zero (for arithmetic types) or a null pointer (for pointer types). C implementations are typically null and null pointer values ​​using a bit pattern consisting exclusively of null bits (although this is not required by the C standard). Therefore, the bss section usually includes all uninitialized variables declared in the file area (that is, outside of any function), as well as uninitialized local variables declared with the static keyword.

0
source

Here's what your chart looks like:

  heap stack rodata bss | | | | | | | | |"abc"|<-+ | c1 |--->|"abc"|<---| c2 | | | | | | | | | | | | +-| c3 | | | | | | | | | | | | | 

c3 is declared the same as c1. They are both on the stack.

-1
source

Source: https://habr.com/ru/post/909545/


All Articles