在 C 中使用 free() 时出现无效(中止)核心转储错误

Posted

技术标签:

【中文标题】在 C 中使用 free() 时出现无效(中止)核心转储错误【英文标题】:Invalid (Aborted)core dumped error while using free() in C 【发布时间】:2020-01-14 14:05:17 【问题描述】:

代码如下: 谁能解释这个问题 如何在 main 中释放 s 的内存

char *get(int N)

    char *s=malloc(10*sizeof(char));  
    s="hello";  
    return s;  

 int main()  
  
    char *s=get(4);  
    printf(s);  
    free(s);  

【问题讨论】:

您正在将 s 的指针值重新分配给静态字符串,而不是像您想象的那样将“hello”实际存储到 malloc 的内存中。因此,您正在释放未分配的内存 strcpy(s,"hello"); char *s=get(6); 在上面@sshashank124所说的伤口上撒盐,你也在泄漏内存。 @P__J__ 如果N 用于任何事情:-) 【参考方案1】:

这里是:

s="hello";

不将"hello" 写入分配的内存。相反,它重新分配s 以指向存储"hello" 的只读位置。您使用malloc 分配的内存泄漏,free(s); 无效,因为您无法释放该只读内存。

如果您想将"hello" 复制到s,请改用strcpy(s,"hello");

【讨论】:

太棒了!但是,如果我想将 N 个字符(即,基于传递的参数)分配给 get 函数中的字符串 s 怎么办? 您可以使用strncpy来限制复制的字符数。 具体来说,我想复制从 'a' 到 N 的字母。所以我应该将它存储在 char 数组中并将其复制到 malloced 字符串吗?但这会浪费一些内存 是的,我还是会那样做。这 26 个字节很可能不会有太大的不同,而且它们很可能在程序的二进制文件中。你可以用一个不断添加到'a' 的循环来组装字母表(例如,'a' + 1b),但这会很复杂,很可能更慢,甚至可能不会节省任何内存。对字母表进行硬编码可能是这里最好的解决方案。 或者您可以使用s = strdup("hello"); 一次性完成分配和复制。然后,如果你没有错误地为s 分配另一个值,你可以调用free(s);【参考方案2】:

通过做

s="hello";

您正在用指向字符串文字"hello" 的第一个元素的指针覆盖malloc() 返回的指针,该指针不是动态分配的。

接下来,您将该指针(指向字符串文字)传递给free(),这会导致未定义的行为。

您可能希望将分配更改为

strcpy(s, "hello");

此外,通过malloc() 覆盖最初返回的指针,您没有机会释放内存 - 因此也会导致内存泄漏。

【讨论】:

【参考方案3】:

这里有两个错误:

    您使用字符串文字“hello”的引用重新分配指针s,从而丢失了malloc分配的内存

    您没有为“hello”字符串分配足够的空间。您至少需要 6 个字符(不是 4 个)

【讨论】:

不是吹毛求疵,this 代码中的实际问题在别处,其他两个答案指出了这一点,而您的答案却没有。 (1) 问题不在于重新分配,而是将无效指针传递给 free 和 (2) 注意,此代码中未使用参数值,因此第 2 点在这里不是有效原因。 @SouravGhosh 不 - 它不在其他地方 - 主要问题是我的观点 1。 好的,如果你这么说的话。我现在停止评论。 传递给get(int N) 的参数在分配的内存中没有任何作用。 malloc 已完成 10 char,因此 point:2 不正确。【参考方案4】:

char * 类型的变量是指向字符的指针(内存地址)。在 C 中,习惯上将字符串实现为以零结尾的字符数组,并通过将 char * 类型的变量用于此类数组的第一个元素来处理字符串。

这样,char * 类型的变量实际上并不包含字符串,它们只是指向它们。

因此,这条线

s="hello";

实际上并不复制字符串的内容,而只是复制字符串的指针(即内存地址)。

如果要复制字符串的实际内容,则必须改用函数strcpy。

通过覆盖用于存储malloc 分配的内存地址的指针,您将字符串文字"hello" 的地址传递给free。不应该这样做。您必须只将内存地址传递给您从malloc 收到的free

【讨论】:

以上是关于在 C 中使用 free() 时出现无效(中止)核心转储错误的主要内容,如果未能解决你的问题,请参考以下文章

删除对象时出现段错误 - GDB 在 free() 中说

随机错误核心转储:`./a.out' 中的错误:free():下一个大小无效(快速):0x00000000010e8d70 *** 中止(核心转储)

使用 JSch 时出现“无效的私钥”

gcc编译程序时出现 double free or corruption (out) 报错的解决办法

启动 Intel python3.7 shell 时出现意外错误:无法执行任何命令 - 中止错误

windows spyder 运行 py 文件时出现无效语法错误