【问题标题】:compilation break when reallocating the memory in C在 C 中重新分配内存时编译中断
【发布时间】:2012-11-27 14:42:45
【问题描述】:

我正在尝试一个例子

int main(){
    int count = 5;
    char *a = "JOSUA";
    char *c = "JANETALAE";
    char *b = NULL;
    char *d = NULL;
    b = (char *)malloc(sizeof(char)*5);
    b = a;
    if(b == NULL){
        printf("\n malloc failed");
    }
    printf("\nChar is:%s\n",b);
    d = (char *)realloc(b,sizeof(char) * 9);
    if(d == NULL){
        printf("\n realloc failed");
    }
    else{
        b = d;
        b = c;                                                                                                                                                                             
    }
    printf("\nChar is:%s\n",b);
    return 0;
}

我正在尝试一个示例程序来分配和重新分配内存。但我无法重新分配内存并获得编译中断,如下所示。

Char is:JOSUA
*** glibc detected *** ./realloc: realloc(): invalid pointer: 0x080485b4 ***
======= Backtrace: ========= /lib/libc.so.6[0x88ffd1] /lib/libc.so.6(realloc+0x2cf)[0x89613f] /lib/libc.so.6(realloc+0x2e7)[0x896157] ./realloc[0x80484aa] /lib/libc.so.6(__libc_start_main+0xe6)[0x836e16] ./realloc[0x8048391]
======= Memory map: ======== 007fc000-0081c000 r-xp 00000000 fd:00 659977     /lib/ld-2.12.90.so 0081c000-0081d000 r--p 0001f000 fd:00 659977     /lib/ld-2.12.90.so 0081d000-0081e000 rw-p 00020000 fd:00 659977     /lib/ld-2.12.90.so 00820000-009ad000 r-xp 00000000 fd:00 660018     /lib/libc-2.12.90.so 009ad000-009af000 r--p 0018c000 fd:00 660018     /lib/libc-2.12.90.so 009af000-009b0000 rw-p 0018e000 fd:00 660018     /lib/libc-2.12.90.so 009b0000-009b3000 rw-p 00000000 00:00 0  00a29000-00a45000 r-xp 00000000 fd:00 660039     /lib/libgcc_s-4.5.1-20100924.so.1 00a45000-00a46000 rw-p 0001b000 fd:00 660039     /lib/libgcc_s-4.5.1-20100924.so.1 00a84000-00a85000 r-xp 00000000 00:00 0          [vdso] 08048000-08049000 r-xp 00000000 fd:02 9440701    /home/user/beata/c_samples/realloc 08049000-0804a000 rw-p 00000000 fd:02 9440701    /home/user/beata/c_samples/realloc 092ac000-092cd000 rw-p 00000000 00:00 0          [heap] b78bc000-b78bd000 rw-p 00000000 00:00 0  b78d3000-b78d5000 rw-p 00000000 00:00 0  bfbd8000-bfbf9000 rw-p 00000000 00:00 0          [stack] Aborted (core dumped)

无法理解为什么会发生编译中断。

【问题讨论】:

  • 您为b 变量分配内存,然后将b 变量分配给您的字符串文字a。您必须将a 的内容复制到b
  • 注意,你不是mallocing 的空间来容纳每个字符串末尾的\0。即使你解决了无法复制它们的问题,你也会遇到它们不再是字符串的问题。
  • 你得到的错误不是编译错误,是运行时错误...
  • 停止将void* 明确地转换为其他指针类型。这不是必需的,甚至可能是有害的! C 不是 C++,该死。
  • @Eregrith:他试图将a 的字符串复制到b。如果您不了解更多信息(并且被教导将 char*s 视为字符串),那么尝试一下是明智的,但是是的 - 它并没有按照他的想法做。

标签: c memory memory-management malloc


【解决方案1】:

您不能在静态内存变量(实际上是 a)上使用 realloc:

b = (char *)malloc(sizeof(char)*5);
b = a;

【讨论】:

  • 使用 fprintf(stderr, "..."); 也更有用调试时,因为它会等到文本打印出来。
  • 添加到答案中,char *a = "JOSUA"; 基本上是 const char * 所以 b=a;那么重新分配 b 是一个错误。
【解决方案2】:

也许可以替换:

b=a;

与:

strcpy(b,a);

会让你朝着正确的方向前进。我想也许你认为这就是b=a; 实际上在做什么?

但请确保您在堆上分配了足够的内存,即不要忘记字符串末尾隐含的 '\0',例如

b = (char *)malloc(sizeof(char)*5);

应该是:

b = malloc(6);

如果你想把"JOSUA"放进去("JOSUA"实际上是"JOSUA\0"

【讨论】:

    【解决方案3】:

    正如错误所说,您正在传递一个无效指针到realloc()

    来自这一行:

    b = a;
    

    用字符串文字的地址覆盖malloc() 的返回值。你不能把它传递给realloc()

    你在这个程序中的整体逻辑非常糟糕;如果malloc() 失败,几乎没有理由相信realloc() 会成功(假设上面的行是一个编辑错误,不应该出现)。

    另外,这是一个运行时错误,而不是你说的“编译错误”。

    此外,典型的错误适用:

    1. 在 C 中,don't cast the return value of malloc()。这同样适用于realloc()
    2. 不要用sizeof (char),只是写1很麻烦。

    【讨论】:

    • 也不写1。每次都写any_variable = malloc(sizeof(*any_variable)*count),这样你甚至不需要思考。
    • 我会遵循这个。谢谢埃瑞格里斯
    【解决方案4】:
     b = (char *)malloc(sizeof(char)*5);
     b = a;
    

    您刚刚丢失了malloc 返回的地址。

    您需要将malloc 返回的地址传递给realloc,如果您传递任何其他地址会导致未定义行为,这就是您的代码所做的。

    【讨论】:

      【解决方案5】:

      您尝试重新分配尚未 malloc 的内存:

        9     b = (char *)malloc(sizeof(char)*5);
       10     b = a;
      

      你这里的第 9 行到第 10 行就失效了,malloc 返回的地址丢失了。 另外,do not cast the return of malloc 因为这可以隐藏其他错误。

      【讨论】:

        【解决方案6】:

        这是行:

        10     b = a;
        

        在这里,您将指针 b 设置为存储在指针 a 中的地址。所以 b 现在指向字符串“JOSHUA”。

        当您尝试重新分配 b 时,您正在向它提供该地址,该地址最初不是由 malloc 分配的。您要做的是将字符串从 a 复制到 b:

        strcpy(b,a);
        

        但是,您需要增加 b 指向的内存大小。

        【讨论】:

          【解决方案7】:

          问题是 b = (char *) malloc(sizeof(char) * 5); 然后立即更改 b 指向的地址 通过分配 a 指向的基地址。 即 b = a; /* 这是错误 */。 对于重新分配,您必须传递 malloc 返回的地址, 不是 a 指向的基地址。

          【讨论】:

            猜你喜欢
            • 2015-08-31
            • 1970-01-01
            • 2014-11-02
            • 1970-01-01
            • 1970-01-01
            • 2018-09-29
            • 2014-03-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多