6
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 should be on the stack;

c2 is a static pointer, it should be on the heap;

c3 is on the heap.

According to my assumption, I draw a graph about the pointers and the string literal they're pointing,

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

My assumption and graph right?

Still, I don't quite understand why should c3 be on the heap? c3 is just a char *, just pointing to an address (located on the heap) doesn't make c3 on the heap, right?

2
  • 1
    No, c3 points to an array in the heap which now contains "abc"; c2 should reside in the BSS. c1, though, is on the stack. Commented Feb 28, 2012 at 12:28
  • 1
    c3 is on the stack, but points to the heap. Commented Feb 28, 2012 at 12:28

6 Answers 6

9

Your assumption is not right. c3 does not point to the literal "abc". It points to the memory returned to by malloc, which you copy in.

Also, c1 and c3 are both in automatic storage (on the stack). They are pointers in the function scope. The objects c3 points to is, however, in dynamic storage (the heap), but c3 itself is not.

A more correct graph is:

 stack         rodata           heap        global
|    |       |       |         |       |   |      |
| c1 |------>| "abc" |<--------------------|  c2  |
| c3 |------------------------>| "abc" |
|    |       |       |         |       |
|    |       |       |         |       |
Sign up to request clarification or add additional context in comments.

6 Comments

c2 is in .bss segment? And that's a segment where global vars and static vars locate?
@Alcott c2 is in static storage (where statics and globals are, yes).
The place where objects of static storage duration are placed, is often named .bss by compiler people. Check the wiki link in my answer.
@Alcott: No. c2 is not in .bss segment. .bss segment containts statically-allocated variables represented solely by zero-valued bits initially.
@LihO But c2 is a statically-allocated variable. In this case it isn't initialized to zero, but to a given address. From what I have seen from compiler implementations, they don't make a difference between static objects set to zero and those set to a given value, they are typically stored in the same .bss segment.
|
4

The actual variable, c3 is located on the stack, because it's a local variable. However, the data that c3 points to will be on the heap, because the pointer was created with malloc.

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

3 Comments

So, c3's life will be terminated when foo() finishes, right? But if I don't free c3, then the space allocated to c3 will not be collected when foo() finishes, will it?
@Alcott no it will not be free()'d, and you'll have a memory leak.
@nos, yes, memory leak, that's what I'm talking about, :-).
1

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

Correct. Though it could also be allocated in a CPU register.

c2 is a static pointer, it should be on the heap;

No. A variable declared as static, or a variable declared as global ("file scope") all have something called static storage duration. This means that they must be initialized to a known value before the program is called. Unless the programmer initializes them explicitly, the compiler will ensure that they are set to zero.

To make static initialization easier, all such objects of static storage duration are typically placed in a separate, dedicated part of the RAM, often called .bss. It is unlikely that .bss will be placed on the stack.

c3 is on the heap.

The actual pointer C3 is on the stack, but the contents it points at are on the heap. The only variables that are on the heap are those you have dynamically allocated with malloc(). Nothing else is there.

My assumption and graph right?

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

C2 is incorrect, since it resides in .bss. It points at the rodata string literal though, as in your graph.

C3 is incorrect. When you strcpy() something, you make a hardcopy of the string literal in rodata and store that copy in heap, at the area pointed at by C3. C3 itself sits on the stack.

EDIT: Not sure what this graph is worth, but here you go.

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

3 Comments

The only variables that are on the heap are those you have dynamically allocated with malloc(), I don't quite understand this. I think, all those I have allocated with malloc are just memory, but variables are just identifiers, they may point to the memory allocated by malloc, can they variables be on the heap?
@Alcott Indeed, the actual pointer is allocated on the stack. It points at the heap. Take this struct typedef struct{ int x; } X_t; then declare a pointer to it: X_t* ptr; and then allocate memory ptr = malloc(sizeof(X_t));. Now ptr is allocated on the stack, but the struct and its member x is allocated on the heap. &ptr->x will give you an address on the heap.
Hah, beautiful, that's it. :-)
1

c1 and c3 are pointers with auto storage duration. Those 2 pointers live on the stack of your foo() function. What they point to is a different matter.

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

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

c3 points to memory allocated by malloc() which is memory usually referred to as "the heap". You then copy the string "abc" into that memory on the heap.

2 Comments

You probably meant c3 in the last paragraph so I took the libery to edit this.
Umm, it is still incorrect in 3rd paragraph. You better edit this yourself, then I'll upvote :)
0

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

In C, statically-allocated objects without an explicit initializer are initialized to zero (for arithmetic types) or a null pointer (for pointer types). Implementations of C typically represent zero values and null pointer values using a bit pattern consisting solely of zero-valued bits (though this is not required by the C standard). Hence, the bss section typically includes all uninitialized variables declared at file scope (i.e., outside of any function) as well as uninitialized local variables declared with the static keyword.

Comments

-1

This is what your diagram should look like:

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.