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

时间:2016-11-06 21:26:35

标签: c pointers memory-management free pass-by-value

我不明白为什么我在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   $0x1, %eax

我希望任何人都可以帮助我,我不知道为什么我会访问错误的指针。

3 个答案:

答案 0 :(得分:1)

您无法修改main中的cells allocate_memory。您正在修改副本。

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

...

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

    ...
}

答案 1 :(得分:0)

C使用pass-by-value进行函数参数传递。如果您想将内存分配给cells本身,则需要

  • 传递指针,或
  • 返回新分配的指针并将其存储回cells中的main()

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

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

答案 2 :(得分:0)

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

外部效果就好像单元格未被函数设置(先前设置为NULL)