Search code examples
csegmentation-faultdynamic-memory-allocationfreestring-literals

Segmentation fault (core dumped) after free(), but I have used malloc()


I'm learning memory allocation in c, and tried the following function, not in main().

// Functions
void manipulateMemory(void)
{
    char *string1 = malloc(5 * sizeof(char));
    // Try to play with sizeof(), but char is defaulted to 1.

    string1 = "Hello";

    printf("%s\n", string1);

    for (int i = 0; i <= 5; i++)
    {
        printf("The char is: %c and location %p.\n", string1[i], &string1[i]);
    }

    free(string1);

    // Always set return at the end
    return;
}

I called the above function by manipulateMemory() in main(). Terminal log is as follow

Hello
The char is: H and location 0x55699a6ef00c.
The char is: e and location 0x55699a6ef00d.
The char is: l and location 0x55699a6ef00e.
The char is: l and location 0x55699a6ef00f.
The char is: o and location 0x55699a6ef010.
The char is:  and location 0x55699a6ef011.
Segmentation fault (core dumped)

Segmentation fault (core dumped) after execution.

If I commented out the free(string1), segmentation fault is gone.

I don't know if I should allocate 5 or 6 to string1 as "\0" might still have to be counted. Sorry for a quick question. How many memories should I allocate to string1?

Anyway, my guess is that the memory allocated with malloc() inside a function is freed once the function return/exit to the main(). This means, with the above code, I actually free the malloc memory twice.

Am I correct? If not, what is the possible mistake I made?

Thanks :)


Solution

  • The function produces a memory leak because at first there was dynamically allocated memory and its address was assigned to pointer string1

    char *string1 = malloc(5 * sizeof(char));
    

    And then the pointer was reassigned with the address of the first character of a string literal

    string1 = "Hello";
    

    So the address of the allocated memory was lost.

    String literals have static storage duration. So you may not apply the function free to a pointer that points to a string literal.

    You need to include header <string.h> to copy the string literal in the allocated memory and write

    #include <string.h>
    
    //...
    
    char *string1 = malloc(6 * sizeof(char));
    // Try to play with sizeof(), but char is defaulted to 1.
    
    strcpy( string1, "Hello" );
    
    printf("%s\n", string1);
    
    for ( int i = 0; string1[i] != '\0'; i++)
    {
        printf("The char is: %c and location %p.\n", string1[i], ( void * )&string1[i]);
    }
    
    free(string1);
    

    Pay attention to that the string literal "Hello" contains 6 characters including the terminating zero character '\0'. You can check that with the following call of printf

    printf( "sizeof( \"%s\" ) = %zu\n", "Hello", sizeof( "Hello" ) );