c-当我试图释放用malloc分配的char指针时,为什么我会得到核心转储



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

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

char *bridge_text;
char menu1[] = "Key input:  nt n. car arrive north 
                            nt s. car arrive south 
                            nt r. empty bridge 
                            nt 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"-键退出程序,但是。。。

  • 如果首先按下'n''e''r'(为bridge_text分配字符串)然后尝试退出,会导致核心转储。如果我删除free()

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

致命错误MapViewOfFileEx共享5'(0x66)Win 32错误6。

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

问题

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

更改

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

bridge_text = malloc(LEN + 1);

使用strcpy 而不是分配bridge_text = north

strcpy(bridge_text, north);

进行时

 bridge_text = north;

和simmilar赋值,则覆盖malloc()返回的实际指针。现在,使用非动态分配的指针(内存)调用free()是未定义的行为。如果你愿意,你可以参考这个答案来了解详细信息。

实际上,要将内容复制到已分配的内存中,您可以(也应该)使用strcpy()。否则,通过分配,您也会造成内存泄漏,因为原始指针会丢失。

然后,

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

也是错误的。你需要把它改成

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

之后,也不要忘记检查malloc()是否成功。

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

当您执行bridge_text = north; 时,您的malloc()'d将丢失

bridge_text被声明为char *。这不像其他语言那样是一个字符串类,它只是指向某个内存的指针,该内存将作为char s的序列读取。

通过将其他值分配给bridge_text,您已经丢失了它的原始值(因此泄露了malloc'd的内存),并将其指向内存的另一部分。这就是为什么当您尝试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 ); 

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

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

建议使用"strcpy()"将字符串复制到bridge_text指向的位置

相关内容

  • 没有找到相关文章

最新更新