【问题标题】:Run-time error: *** glibc detected *** [closed]运行时错误:***检测到 glibc *** [关闭]
【发布时间】:2016-07-22 12:56:17
【问题描述】:

我正在尝试一些随机的东西,以了解更多关于 malloc、realloc 和 free 以及它们一起使用时的行为方式。

我将包含代码和我的想法。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
   char *str;

   /* Initial memory allocation */
   str = (char *) malloc(15);
   strcpy(str, "63tczfqV4nqB2YnH9iFJbGvGyyDkvK341rrj0G0mo1PEYniOVHejVIFIQnJzHSSMRbuyGMCZ4M5HFMV4y1q4QgYqyxp2XkTjxaolKTkaw1r25S2Emz061tw1");
   printf("String = %s,  Address = %u\n", str, *str);

   /* Reallocating memory */
   str = (char *) realloc(str,16);
   strcat(str, "12345678");
   printf("String = %s,  Address = %u\n", str, *str);

   free(str);
   return 0;
}

我希望我的代码表现如下:

  1. 我使用 malloc 创建了一个字符型内存指针,指向(最多)15 个字节的内存。
  2. 使用那个字符指针,我使用 strcpy 保存了 120 个字符。
  3. 我将字符指针的大小调整为现在指向(最多)16 个字节。
  4. 我使用 strcat 将另外 8 个字符连接到已保存 120 个字符的内存缓冲区。
  5. 现在,我的字符指针应该指向 128 个字符,我试图重现这一点,但是,对于 128 个字符它失败了(但打印了使用 strcpy 保存的早期 120 个字符)。

确切的错误是这样的:

 ***** glibc detected *** ./a.out: realloc(): invalid next size: 0x0000000001690010 *****

控制台挂在上面,也就是说,我想它从未超过 realloc 行?

【问题讨论】:

  • 您的代码有未定义的行为。您已经malloced 15 个字符的存储空间,然后strcpy 超出了此分配的限制。投反对票并投票结束。
  • 所以如果我想保存 120 个字符,我应该使用 malloc(120) 吗?我希望它是 15 个字节(不是 15 个字符)。
  • 您的初始 malloc 必须至少是该字符串的长度 + 1(1 表示终止 '\0')。在 C 中,分配的大小以chars/bytes 为单位,在这种情况下恰好是 8 位。 (标准说:字节可寻址的数据存储单元大到足以容纳执行环境的基本字符集的任何成员)
  • @Avineshwar:在这种情况下,你真的应该首先阅读一本 C 书籍并理解其内容。在尝试跑步之前了解如何走路。
  • @AnttiHaapala:实际上“字节”和char 是标准中的同义词。宽度没有区别。

标签: c pointers malloc glibc realloc


【解决方案1】:

让我们看一下代码的前两行:

str = (char *) malloc(15);
strcpy(str, "63tczfqV4nqB2YnH9iFJbGvGyyDkvK341rrj0G0mo1PEYniOVHejVIFIQnJzHSSMRbuyGMCZ4M5HFMV4y1q4QgYqyxp2XkTjxaolKTkaw1r25S2Emz061tw1");

此时,您已经打破了 C 语言的规则。 strcpy 将写到 str 的末尾,这会导致未定义的行为。

在此之后发生的一切都悬而未决。

【讨论】:

  • 所以如果我想保存 120 个字符,我应该使用 malloc(120) 吗?我希望它是 15 个字节(不是 15 个字符)。
  • @Avineshwar:一个 120 个字符的字符串(可能用 ASCII 编码)需要 120+1 个字节的空间。额外的字节用于标记字符串的结尾。
  • 我刚刚看到我没有提到这一点。我知道这一点。谢谢你让它浮出水面。我正在尝试修改程序,不完全是为了了解 malloc、realloc 和 .free 是如何工作的,而是为了了解我能在多大程度上重现我对 C 的与内存相关的理解。我猜现在有相当多的不清楚.
  • 我做了需要解释的修改。 str = (char *) malloc(15) 现在是 str = (char *) malloc(120) str = (char *) realloc(str,16) 现在是 str = (char *) realloc(str,127) strcat( str, "12345678") 现在是 strcat(str, "123456781234567") 我发现它适用于 strcat(str, "123456781234567") 但不适用于这个 strcat(str, "1234567812345678") 即某种访问冲突。这是为什么呢?
  • 您的最后一个字符串需要 17 个字节。字符串文字需要一个额外的字节用于终止空字符。
最近更新 更多