简体   繁体   中英

Why do I get core dump when I try to free a char pointer allocated with malloc?

I'm trying to learn about the basics in C and I can't quite get malloc() and free() to work.

This is my code that's going to print a word in the center of the screen depending on input. (removed some declarations and includes to shorten it)

char *bridge_text;
char menu1[] = "Key input:  \n\t n. car arrive north \
                            \n\t s. car arrive south \
                            \n\t r. empty bridge \
                            \n\t q. quit";
int main()
{
    bridge_text = malloc(sizeof(char)*(LEN+1)); //misprinted here before

    initscr();
    getmaxyx(stdscr,row, col);

    mvprintw(2, 4, menu1);
    refresh();
    while(run)
    {
        switch(getchar())
        {
            case 'q':
                run = 0;
                break;
            case 'n':
                /*not shown: char north[] = "NORTH";*/
                bridge_text = north; 
                break;
            case 's':
                bridge_text = south;
                break;
            case 'r':
                bridge_text = empty;
                break;
            default:
                bridge_text = empty;
                break;
        }

        mvprintw(row/2, (col-5)/2, bridge_text);
        refresh();
    }
    endwin();

    /* adding free() here results in core dump. */
    free(bridge_text);

    return 0;}

I use gcc with cygwin and the program is executed properly and I can quit the program using 'q'-key, however...

  • If first press 'n' , 'e' or 'r' (assign bridge_text a string) and then try to exit, it results in a core-dump. This works fine if I remove free()

I do have an error when running executables with cygwin: *

fatal error MapViewOfFileEx shared 5'(0x66) Win 32 error 6.

maybe that's the problem but I assumed it wasn't related to this.

Problems

  1. sizeof(LEN+1) will evaluate to size of an integer
  2. Dynamically allocated memory is lost when string is assigned

Change

bridge_text = malloc(sizeof(LEN+1));

to

bridge_text = malloc(LEN + 1);

and instead of assigning bridge_text = north , use strcpy

strcpy(bridge_text, north);

While doing

 bridge_text = north;

and simmilar assignments , you're overwriting the actual pointer returned by malloc() . Now, calling free() with non-dynamically allocated pointer (memory) is undefined behaviour . If you want, you can refer this answer for details .

Actually, to copy the content to already allocated memory, you can (and should) use strcpy() . Otherwise, by assigning , you're also creating memory leak , as the original pointer is lost.

Then,

 bridge_text = malloc(sizeof(LEN+1));

is also wrong. You need to change that to,

 bridge_text = malloc(LEN+1);   //sizeof(char) is 1 in c

After that, don't forget to check for the success of malloc() , too.

You cannot call free() on a non-dynamically allocated pointer.

What you malloc() 'd is lost when you do bridge_text = north;

bridge_text is declared as char * . This is not a string class as other languages have - it is simply a pointer to some memory that is to be read as a sequence of char s.

By assigning other values to bridge_text you have lost its original value (and therefore leaked the memory you malloc 'd) and pointed it at another part of memory. This is why your program crashes when you try to free(bridge_text) - the pointer is no longer valid for freeing.

Also, as an aside, the sizeof operator gets the byte size of whatever you pass it - in this case a, presumably, integer constant - so you are actually only allocating 5 or 9 bytes (depending on system), not (LEN + 1) .

You have a number of options to fix your code:

  • Don't dynamically allocate your char buffer. Change the declaration to char bridge_text[LEN + 1] and remove the malloc and free calls. Then use strcpy to populate it with data.
  • Simply use bridge_text as a pointer to other buffers containing items you want to print. This works if everything is constant or you put anything dynamic in a separate buffer (don't forget to make sure your dynamic buffer doesn't go out of scope though), eg

     char dynamic_string [50]; int value = 10; sprintf(dynamic_string,"Value = %d", value); bridge_text = dynamic_string; 
  • Keep using it as you are but fix your malloc size issue and change the bridge_text = <something> to strcpy(bridge_text,<something>) .

This kind of line:

bridge_text = north; 

does not copy the text string in north[] to the char array bridge_text[].

it only copies pointers..

suggest:

strcpy( bridge_text, north ); 

in the current code, the malloc'd pointer in bridge_text is being overlayed by the assignment statements.

That is why the free() causes an abort.

suggest using 'strcpy()' to copy the strings into where bridge_text points

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM