hgiesel
hgiesel

Reputation: 5658

Pointer being freed was not allocated / Segfault

I thought I understood how dynamic memory worked basically, but I did the following. I use this function to allocate dynamic memory:

int get_alota_mem(char*** const ptr)
{
    int result = EXIT_SUCCESS;
    bool success = true;

    if (success && (*ptr = calloc(10, sizeof **ptr)) == NULL)
    {
        result = EXIT_FAILURE;
        success = false;
    }

    for (int i = 0; i < 10; i++)
    {
        if (success && ((*ptr)[i] = calloc(20, sizeof ***ptr)) == NULL)
        {
            result = EXIT_FAILURE;
            success = false;
        }
    }

    return result;
}

I use this function to free the allocated dynamic memory:

void free_alota_mem(char** const ptr)
{
    for (int i = 0; i < 10; i++)
    {
        free(ptr[i]);  // segfault!
        ptr[i] = NULL;
    }

    free(ptr);
}

In between those two calls I can use the memory and don't encounter any segfaults. But when I try to free the memory, I get a segfault with the first value I try to free.

I know I could just do char* ptr[10] and just use an auto allocated array instead of a dynamically allocated pointer, which would save me some hassle, but I wanted to try and make this work.

EDIT: My main:

int main(void)
{
    char** mem = NULL;
    get_alota_mem(&mem);
    mem[0] = "Hello";
    mem[1] = "world";
    free_alota_mem(mem);
}

Upvotes: 0

Views: 54

Answers (1)

MikeCAT
MikeCAT

Reputation: 75062

You tried to free string literals. Passing pointer that is not NULL and not what is allocated via memory management functions such as malloc() to free() will invoke undefined behavior.

To copy strings, use strcpy() function.

#include <string.h>

int main(void)
{
    char** mem = NULL;
    get_alota_mem(&mem);
    strcpy(mem[0], "Hello");
    strcpy(mem[1], "world");
    free_alota_mem(mem);
}

Upvotes: 4

Related Questions