【问题标题】:Can't understand this error while freeing memory in C在 C 中释放内存时无法理解此错误
【发布时间】:2017-03-20 04:18:30
【问题描述】:

我不明白为什么我会在 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

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

【问题讨论】:

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


【解决方案1】:

您没有在allocate_memory 中修改您的main 的cells。您正在修改副本。

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

...

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

    ...
}

【讨论】:

    【解决方案2】:

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

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

    • 返回新分配的指针并将其存储回main()中的cells。

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

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

    【讨论】:

      【解决方案3】:

      分配函数不返回新分配的块。 分配内存(单元);

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-04
        • 1970-01-01
        • 2014-04-02
        • 1970-01-01
        • 1970-01-01
        • 2018-04-04
        • 1970-01-01
        相关资源
        最近更新 更多