在 C 中释放内存时无法理解此错误

Can't understand this error while freeing memory in C

我不明白为什么我在 free_memory 函数中出现分段错误。这是程序:

#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;
}

调试器显示有关错误的消息:

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   [=11=]x1, %eax

我希望任何人都可以帮助我,我不明白为什么我正在访问一个错误的指针。

C 在函数参数传递中使用按值传递。如果您想将内存分配给 cells 本身,则需要

  • 传递一个指向它的指针,或者

  • return 新分配的指针并将其存储回 cells in main().

    否则,allocate_memory() 函数中的 cells 是本地的,一旦您从该函数 return 对 cells 所做的任何更改都将丢失。

因此,在 free_memory() 函数内部,访问 cells[i] 是无效的,因为 cells 根本没有指向任何有效内存。尝试访问无效内存调用 undefined behavior.

分配函数不return新分配的块。 allocate_memory(细胞);

外部效果好像单元格没有被函数设置(之前设置为NULL)

您没有在 allocate_memory 中修改 maincells。您正在修改副本。

如果要修改函数中的指针,必须将指针传递给函数:

...

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);

    ...
}