当我尝试释放使用 malloc 分配的字符指针时,为什么会出现核心转储?

Why do I get core dump when I try to free a char pointer allocated with malloc?

我正在尝试学习 C 语言的基础知识,但我无法完全掌握 malloc()free() 的工作。

这是我的代码,它将根据输入在屏幕中央打印一个单词。 (删除了一些声明并包括以缩短它)

char *bridge_text;
char menu1[] = "Key input:  \n\t n. car arrive north \
                            \n\t s. car arrive south \
                            \n\t r. empty bridge \
                            \n\t q. quit";
int main()
{
    bridge_text = malloc(sizeof(char)*(LEN+1)); //misprinted here before

    initscr();
    getmaxyx(stdscr,row, col);

    mvprintw(2, 4, menu1);
    refresh();
    while(run)
    {
        switch(getchar())
        {
            case 'q':
                run = 0;
                break;
            case 'n':
                /*not shown: char north[] = "NORTH";*/
                bridge_text = north; 
                break;
            case 's':
                bridge_text = south;
                break;
            case 'r':
                bridge_text = empty;
                break;
            default:
                bridge_text = empty;
                break;
        }

        mvprintw(row/2, (col-5)/2, bridge_text);
        refresh();
    }
    endwin();

    /* adding free() here results in core dump. */
    free(bridge_text);

    return 0;}

我将 gcc 与 cygwin 一起使用,程序正确执行,我可以使用 'q'-key 退出程序,但是...

当使用 cygwin 执行 运行 可执行文件时,我确实遇到错误:*

fatal error MapViewOfFileEx shared 5'(0x66) Win 32 error 6.

也许这就是问题所在,但我认为这与此无关。

问题

  1. sizeof(LEN+1) 将评估为整数的大小
  2. 分配字符串时动态分配的内存丢失

改变

bridge_text = malloc(sizeof(LEN+1));

bridge_text = malloc(LEN + 1);

而不是分配 bridge_text = north,使用 strcpy

strcpy(bridge_text, north);

您不能在非动态分配的指针上调用 free()

当你bridge_text = north;

时,你malloc()的东西就丢失了

做的时候

 bridge_text = north;

和类似的赋值,你覆盖 malloc()返回的实际指针。现在,使用非动态分配的指针(内存)调用 free()undefined behaviour. If you want, you can refer this answer for details.

实际上,要复制内容到已经分配的内存,你可以(也应该)使用strcpy(). Otherwise, by assigning, you're also creating memory leak,因为原始指针丢失了。

然后,

 bridge_text = malloc(sizeof(LEN+1));

也是错误的。您需要将其更改为,

 bridge_text = malloc(LEN+1);   //sizeof(char) is 1 in c

之后,别忘了检查 malloc() 是否成功。

bridge_text 声明为 char *。这不是其他语言所具有的字符串 class - 它只是指向某个内存的指针,该内存将作为 chars.

的序列读取

通过为 bridge_text 分配其他值,您丢失了它的原始值(因此泄漏了您 malloc 的内存)并将其指向内存的另一部分。这就是当您尝试 free(bridge_text) 时您的程序崩溃的原因 - 指针对于释放不再有效。

此外,sizeof 运算符获取您传递给它的任何内容的字节大小 - 在本例中,大概是整数常量 - 所以您实际上只分配 5 或 9 个字节(取决于在系统上),而不是 (LEN + 1).

您有多种选择来修复您的代码:

  • 不要动态分配您的 char 缓冲区。将声明更改为 char bridge_text[LEN + 1] 并删除 mallocfree 调用。然后使用 strcpy 用数据填充它。
  • 只需使用 bridge_text 作为指向包含您要打印的项目的其他缓冲区的指针。如果一切都是常量或者您将任何动态内容放在单独的缓冲区中(不要忘记确保您的动态缓冲区不会超出范围),这将起作用,例如

    char dynamic_string [50];
    int value = 10;
    sprintf(dynamic_string,"Value = %d", value);
    bridge_text = dynamic_string;
    
  • 继续按原样使用它,但解决 malloc 尺寸问题并将 bridge_text = <something> 更改为 strcpy(bridge_text,<something>)

这种行:

bridge_text = north; 

不会将 north[] 中的文本字符串复制到 char 数组 bridge_text[]。

它只复制指针..

建议:

strcpy( bridge_text, north ); 

在当前代码中,bridge_text 中的 malloc 指针被赋值语句覆盖。

这就是 free() 导致中止的原因。

建议使用'strcpy()'将字符串复制到bridge_text点