Search code examples
cpointersmemory-managementfreepass-by-value

Can't understand this error while freeing memory in C


I don't understand why I m am getting a segmentation fault inside the free_memory function. Here is the program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void allocate_memory (char **cells)
{
    int i;

    cells = (char **) malloc(9 * sizeof(char *));
    if (cells == NULL)
    {
        perror("Couldn't allocate memory");
        exit(1);
    }

    for (i = 0; i < 9; i++)
    {
        cells[i] = (char *) malloc(9 * sizeof(char));
        if (cells[i] == NULL)
        {
            perror("Couldn't allocate memory");
            exit(1);
        }

        memset(cells[i], 1, 9);
    }
}

void free_memory (char **cells)
{
    int i;

    for (i = 0; i < 9; i++)
    {
        free(cells[i]);
    }

    free(cells);
}

int main (int argc, char *argv[])
{
    char **cells = NULL;

    allocate_memory(cells);
    printf("Allocated\n");
    free_memory(cells);

    return 0;
}

The debugger shows this message about the error:

Process 1433 launched: '/Users/Jaime/Documents/workspaceC/PruebasC/PruebasC/sk' (x86_64)
Allocated
Process 1433 stopped
* thread #1: tid = 0x1058a, 0x0000000100000e95 sk`free_memory + 37, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000100000e95 sk`free_memory + 37
sk`free_memory:
->  0x100000e95 <+37>: movq   (%rcx,%rax,8), %rdi
    0x100000e99 <+41>: callq  0x100000f20               ; symbol stub for: free
    0x100000e9e <+46>: movl   -0xc(%rbp), %eax
    0x100000ea1 <+49>: addl   $0x1, %eax

I hope anyone can help me, I don't get why I am accessing a bad pointer.


Solution

  • You are not modifying your main's cells in allocate_memory. You are modifying a copy.

    If you want to modify a pointer in a function, you have to pass a pointer-to-pointer to the function:

    ...
    
    void allocate_memory (char ***cells)
    {
        int i;
    
        *cells = (char **) malloc(9 * sizeof(char *));
        if (*cells == NULL)
        {
            perror("Couldn't allocate memory");
            exit(1);
        }
    
        for (i = 0; i < 9; i++)
        {
            (*cells)[i] = (char *) malloc(9 * sizeof(char));
            if ((*cells)[i] == NULL)
            {
                perror("Couldn't allocate memory");
                exit(1);
            }
    
            memset((*cells)[i], 1, 9);
        }
    }
    
    ...    
    
    int main (int argc, char *argv[])
    {
        char **cells = NULL;
    
        allocate_memory(&cells);
    
        ...
    }