当我尝试释放分配了malloc的char指针时,为什么会得到核心转储?

时间:2015-06-30 15:01:04

标签: c malloc free

我试图了解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退出程序,但是......

  • 如果首先按'n''e''r'(指定bridge_text一个字符串), 然后尝试退出,它会导致核心转储。如果我,这工作正常 删除free()

使用cygwin:*

运行可执行文件时出错
  

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

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

6 个答案:

答案 0 :(得分:4)

问题

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

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

    bridge_text = malloc(LEN + 1);
    

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

    strcpy(bridge_text, north);
    

答案 1 :(得分:3)

在你的评论中,你有:

bridge_text = north; 

然后你做:

north

表示您将bridge_text的地址存储在free(bridge_text)中。然后你尝试north - 这意味着你试图释放free - 但你不能这样做,你只能使用malloc分配north个数据,这个情况不是malloc

当您bridge_text = north;某事并将其结果分配给指针,然后为该指针指定其他内容时(就像您现在使用malloc(sizeof(LEN+1))所做的那样),通常会丢失指向最初分配的数据的指针和泄漏的记忆。所以你不应该这样做。

备注不使用malloc(LEN + 1),而使用zii.widgets.grid.CGridView也是正确的。

答案 2 :(得分:2)

在做的时候

 bridge_text = north;

和simmilar 分配,您覆盖 malloc()返回的实际指针。现在,使用非动态分配的指针(内存)调用free()undefined behaviour。如果您愿意,可以refer this answer for details

实际上,要将复制内容复制到已分配的内存,您可以(并且应该)使用strcpy()。否则,通过分配,您还会创建memory leak,因为原始指针会丢失。

然后,

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

也错了。您需要将其更改为,

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

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

答案 3 :(得分:0)

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

执行malloc()

时,bridge_text = north;' d丢失了什么

答案 4 :(得分:0)

bridge_text被声明为char *。这不是其他语言所具有的字符串类 - 它只是指向某些内存的指针,该内存将被视为char s的序列。

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

另外,另外,sizeof运算符获取传递它的任何字节大小 - 在本例中为a,可能是整数常量 - 因此实际上只分配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>)

答案 5 :(得分:0)

这种路线:

bridge_text = north; 

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

它只复制指针..

建议:

strcpy( bridge_text, north ); 

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

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

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