Reputation: 2742
I was learning C and playing a bit with heap memory when I encountered this:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char* test = malloc(1024);
test = "Hello!";
printf("%s\n", test);
free(test);
return 0;
}
What I think it should do:
stdout
from the start of the pointer I got from malloc()
till it finds a \0
malloc()
But, my program just crashes when free()
is called. Why?
~$ ./mem
Hello!
*** Error in `./mem': munmap_chunk(): invalid pointer: 0x0000000000400684 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7f9f99ac5725]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x1a8)[0x7f9f99ad1c18]
./mem[0x4005ec]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f9f99a6e830]
./mem[0x4004e9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 3801151 /home/gala/mem
00600000-00601000 r--p 00000000 08:01 3801151 /home/gala/mem
00601000-00602000 rw-p 00001000 08:01 3801151 /home/gala/mem
015e6000-01607000 rw-p 00000000 00:00 0 [heap]
7f9f99838000-7f9f9984e000 r-xp 00000000 08:01 1970703 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f9f9984e000-7f9f99a4d000 ---p 00016000 08:01 1970703 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f9f99a4d000-7f9f99a4e000 rw-p 00015000 08:01 1970703 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f9f99a4e000-7f9f99c0e000 r-xp 00000000 08:01 1970665 /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99c0e000-7f9f99e0d000 ---p 001c0000 08:01 1970665 /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99e0d000-7f9f99e11000 r--p 001bf000 08:01 1970665 /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99e11000-7f9f99e13000 rw-p 001c3000 08:01 1970665 /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99e13000-7f9f99e17000 rw-p 00000000 00:00 0
7f9f99e17000-7f9f99e3d000 r-xp 00000000 08:01 1970637 /lib/x86_64-linux-gnu/ld-2.23.so
7f9f9a013000-7f9f9a016000 rw-p 00000000 00:00 0
7f9f9a039000-7f9f9a03c000 rw-p 00000000 00:00 0
7f9f9a03c000-7f9f9a03d000 r--p 00025000 08:01 1970637 /lib/x86_64-linux-gnu/ld-2.23.so
7f9f9a03d000-7f9f9a03e000 rw-p 00026000 08:01 1970637 /lib/x86_64-linux-gnu/ld-2.23.so
7f9f9a03e000-7f9f9a03f000 rw-p 00000000 00:00 0
7ffcc81cb000-7ffcc81ec000 rw-p 00000000 00:00 0 [stack]
7ffcc81f8000-7ffcc81fa000 r--p 00000000 00:00 0 [vvar]
7ffcc81fa000-7ffcc81fc000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
[1] 12941 abort ./mem
Upvotes: 3
Views: 3730
Reputation: 96246
Welcome to the complex world of C!
Basically, you're overwriting your pointer test
with an address of "Hello!"
(which is static immutable array).
And it crashes because you try to free a thing that you have not created.
You should use strcpy()
or a loop to copy your string into text
.
Upvotes: 3
Reputation: 33511
As in the comments, this is what going on:
int main(void) {
char* test = malloc(1024); /* You allocate, great! */
test = "Hello!"; /* Huh, what's this? You point 'test'
* to some area in the code section.
* Valid, but considering you just
* allocated some memory, strange */
printf("%s\n", test); /* Print out a string from the code
* section: fine. */
free(test); /* What?! You want to try to free() the
* memory in the code section? That's a
* big no-no! */
return 0; /* whatever */
}
Now, what you should do:
int main(void) {
char* test = malloc(1024); /* You allocate, great! */
strcpy(test, "Hello!"); /* Copy some data into that
* allocated memory */
printf("%s\n", test); /* Print out a string from the
* heap: fine. */
free(test); /* Free that allocated memory! */
return 0; /* aaaand, we're done */
}
Upvotes: 6
Reputation: 109
test is initially pointing to memory allocated by malloc of size 1024. Now in the next line you are pointing test to memory referenced by "Hello!". So your test pointer is now pointing to "Hello!" and not what you allocated in the first place using malloc. Now you are trying to free "Hello!", which is invalid because this memory is not been allocated using malloc and hence your programming is crashing.
char* test = malloc(1024);
test = "Hello!"; /* This is wrong. You pointer is pointing to "Hello!" string base address */
To store "Hello!" in memory allocated by test, you need to use memcpy. so instead of :
test = "Hello!"
use :
memcpy(test, "Hello!", sizeof("Hello!");
This will fix your code.
Upvotes: 1