Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling free() on malloc()'d char pointer causes program to crash with invalid pointer

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:

  • Allocate 1024 bytes on the heap
  • Write "Hello!\0" to the start of that memory
  • Write to stdout from the start of the pointer I got from malloc() till it finds a \0
  • Free the 1024 bytes of memory allocated with malloc()
  • Return 0

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
like image 202
Gala Avatar asked Mar 22 '26 21:03

Gala


2 Answers

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 */
}
like image 55
Bart Friederichs Avatar answered Mar 25 '26 10:03

Bart Friederichs


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.

like image 39
HolyBlackCat Avatar answered Mar 25 '26 11:03

HolyBlackCat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!