【问题标题】:Why I cannot free a malloc'd string?为什么我不能释放 malloc 的字符串?
【发布时间】:2012-11-22 11:26:12
【问题描述】:

我有这个代码:

#define ABC "abc"

void main()
{
char *s = malloc(sizeof(char)*3);
printf("%p ", s);
s = ABC;
printf("%p ", s);
free(s);
}

这是输出:

0x8927008 0x8048574 Segmentation fault (core dumped)

如您所见,字符串 s 的地址在赋值后发生了变化(我认为这就是 free() 给出 segfault 的原因)。 谁能解释我为什么以及如何发生这种情况? 谢谢!

【问题讨论】:

  • 你丢失了 malloced 内存指针!!
  • 请注意,C 中的 sizeof (char) 始终为 1,因此在上述表达式中包含引用通常是毫无意义的。

标签: c string malloc constants free


【解决方案1】:

线

s = ABC;

s 更改为指向可能位于只读内存中的不同字符串。尝试释放此类内存会导致未定义的行为。很可能会发生崩溃。

我想你想要

strcpy(s, ABC);

相反。这会将字符数组“abc”复制到s。请注意,这将导致进一步的错误 - s 太短并且在 ABC 末尾没有空间用于 nul 终止符。将分配更改为 4 个字节以解决此问题

char *s = malloc(4);

或使用

char *s = malloc(sizeof(ABC));

如果ABC 是您要存储的最大长度。

【讨论】:

    【解决方案2】:

    void main() UBmain 返回int

    printf("%p", s) UB:调用一个函数,该函数接受可变数量的参数,但范围内没有原型; UB:使用 char* 类型的值,其中需要 void* 类型的值。

    free(s) UB:s 不是malloc()的结果

    UBUndefined Behaviour

    【讨论】:

      【解决方案3】:

      之后

      char *s = malloc(sizeof(char)*3);
      

      s 指向 malloc 分配的内存。

      线

      s = ABC;
      

      会变成

      s = "abc";
      

      在占有之后。现在这一步使s 指向只读区域中的字符串文字"abc"。请注意,这也会泄漏分配的内存。

      现在由于s 指向一个非分配的只读内存,释放它是一个未定义的行为。

      如果您想将字符串"abc" 复制到s 指向的内存中,您需要使用strcpy 作为:

      strcpy(s, ABC);
      

      但请注意,要容纳 "abc"s 必须至少有 4 个字符长,才能容纳 NUL 字符。

      【讨论】:

        【解决方案4】:

        换行:char *s = malloc(sizeof(char)*3);

        char *s = (char *)malloc(sizeof(char)*3);

        这清除了许多编译器警告的警告。

        除此之外,我还建议您根据自己的工作使代码更加灵活。如果由于某种原因您将 ABC 更改为“ABCD”,您将没有为所有字符分配足够的空间。

        此外,字符串“ABC”实际上有 4 个字符(因为末尾有一个空字符来终止字符串)。如果没有额外的终止符,您会看到问题。

        【讨论】:

        • 我不确定你在这里推荐什么。如果它只是为 malloc 的返回添加强制转换,请注意这不是 C 编译器所要求的。 (虽然它可能会从 C++ 编译器生成警告。)
        猜你喜欢
        • 2011-01-17
        • 2018-10-02
        • 2016-02-28
        • 2014-12-13
        • 1970-01-01
        • 1970-01-01
        • 2020-03-26
        • 2011-12-29
        • 1970-01-01
        相关资源
        最近更新 更多