【问题标题】:Memory Clobbered内存崩溃
【发布时间】:2012-01-28 03:39:47
【问题描述】:

我对这个回复感到困惑。谁能帮助我并指出我在哪里犯了错误?键盘的输出是“memory clobbered before allocated block”

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

int main(void)
{
    char *s = (char *)malloc(10 * sizeof(char));
    s = "heel";
    printf("%s\n",s);
    printf("%c\n",s[2]);
    printf("%p\n",s);
    printf("%d\n",s);
    free(s);
    return 0;
}

【问题讨论】:

标签: c memory char


【解决方案1】:

您正在尝试通过以下方式释放常量内存:

free(s); // cannot free constant "heel"

您正在做的是分配一块内存并存储其位置 (char *s)。然后,您将用 1 覆盖对字符串常量“heel”(内存泄漏)的引用,该引用不能是 freed。要使其行为符合要求,您应该将常量字符串复制到您分配的内存中:

strcpy(s, "heel");

这是获取用户输入的示例:

char *input = malloc(sizeof(char) * 16); // enough space for 15 characters + '\0'
fgets(input, 16, stdin);

// do something with input

free(input);

【讨论】:

  • 谢谢蒂姆。那么这意味着使用 malloc 来初始化内存和 s = "heel" 是两个不同的东西吗? s="heel" 会自动初始化内存吗?
  • @kevin:当你的程序启动时,字符串常量“heel”存储在内存中,是只读的; s = "heel" 将 s 分配给该只读字符串的位置。因此,当您尝试free(s) 时,您会收到错误消息。
  • 如果我想从键盘输入一个字符串并在完成后释放内存会发生什么?
【解决方案2】:
char *s = (char *)malloc(10 * sizeof(char));
  s = "heel";

不符合您的想法,或者您对更现代语言的期望

第一行为 10chars 分配一些内存并返回它的地址。

第二行将该地址更改为指向在编译时分配的一个常量内存块,其中包含“heel”丢失指向已分配内存的链接 - 泄漏它

【讨论】:

    【解决方案3】:

    你不能free(s) - 它是不变的记忆。

    尝试将s = "heel";更改为strcpy(s,"heel");

    【讨论】:

      【解决方案4】:

      扩展@TimCooper 的回答:

      • 首先你要做:char *s = (char *)malloc(10 * sizeof(char));
      • 然后:s = "heel";

      第一行分配内存并将该内存的位置分配给s。但是第二行将s重新分配给栈上常量字符串heel的内存位置!

      这意味着您尝试释放堆栈上的内存,这是非法的。 并且您会泄漏内存,因为您最初分配给 s 的内容现在无法访问。

      如果你想将字符串写入s 指向的内存,你应该使用strcpy()(或者,更好的是strncpy())。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-14
        • 1970-01-01
        • 2013-06-23
        • 2014-11-22
        • 2013-04-27
        • 2011-09-25
        • 2016-10-09
        • 2016-02-21
        相关资源
        最近更新 更多