I'm very confused about what's happening. I always thought char *
and char []
were interchangable, but after looking at the memory addresses it seems char *
allocates space in the heap, whereas char []
is allocating memory on the stack.
char stack[] = "hello"; char *heap = "hello"; char *heap_string_malloc = malloc(5); heap_string_malloc = "hello"; printf("Address of stack[0]: %p\n", stack); printf("Address of heap[0]: %p\n", heap); printf("Address of heap_string_malloc[0]: %p\n", heap_string_malloc);
Outputs the following:
Address of stack[0]: 0x7fff8b0b85b0 Address of heap[0]: 0x400760 Address of heap_string_malloc[0]: 0x400760
Does this mean that char *
is dynamically allocated?
Further to my confusion, how come malloc
is allocating the same memory address as what char *heap
has already allocated? I'm not running any optimisation (simply gcc file.c
).
Local variable buffers that are declared as a constant size (see the below example), or initialized immediately are stored on the stack. char x[20]; or char x[] = "this buffer"; Even if they are then passed to a function the variable will remain stored on the stack.
For the array, the total string is stored in the stack section, but for the pointer, the pointer variable is stored into stack section, and content is stored at code section. And the most important difference is that, we cannot edit the pointer type string.
You can have pointers to pointers: char **s2 = &s; s2 just stores the address of the variable s . Pointers to pointers come up when you're dealing with arrays of pointers, or when you're passing a pointer to a function and you want the function to be able to write a new pointer value.
Stack accesses local variables only while Heap allows you to access variables globally. Stack variables can't be resized whereas Heap variables can be resized. Stack memory is allocated in a contiguous block whereas Heap memory is allocated in any random order.
Arrays are not pointers. What your program is doing, line by line, is
// Allocate 6 bytes in the stack and store "hello" in them char stack[] = "hello"; // Allocate pointer on the stack and point it to a static, read-only buffer // containing "hello" char *heap = "hello"; // Malloc 5 bytes (which isn't enough to hold "hello" due to the NUL byte) char *heap_string_malloc = malloc(5); // Reset heap_string_malloc to point to a static buffer; memory leak! heap_string_malloc = "hello";
The reason you're seeing the same pointer twice is because the compiler optimized away the second static buffer containing "hello"
.
When you do e.g.
char *heap = "hello";
the pointer heap
actually does not point to the heap, it points to static data loaded together with the rest of program by the operating system loader. In fact, to be correct it should be
const char *heap = "hello";
as heap
is pointing to a constant and read-only piece of memory.
Also, while arrays decays to (and can be used as) pointers, and pointers can be used with array syntax, they are not the same. The biggest difference being that for an array you can use e.g. sizeof
to get the size in bytes of the actual array, while it's not possible for pointers.
And as a third thing, when you're doing
char *heap_string_malloc = malloc(5); heap_string_malloc = "hello";
you have a memory leak, as you first assign something to heap_string_malloc
but then directly afterward reassign heap_string_malloc
to point to something completely different.
As for the reason you get the same address for both heap
and heap_string_malloc
it's because both points to the same literal string.
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