C 自由函数失败

C 自由函数失败,c,malloc,free,C,Malloc,Free,我正在用Linux编写一个简单的程序。其目的是显示GNU版本号。但是free()函数似乎在向我尖叫。当我执行程序时。它显示了以下内容: *在“./a.out”中出错:munmap_chunk():无效指针:0x00007fa89f028d8a* 以及回溯和内存映射 下面是我的代码: # include <stdio.h> # include <gnu/libc-version.h> # include <string.h> # include <stdl

我正在用Linux编写一个简单的程序。其目的是显示GNU版本号。但是
free()
函数似乎在向我尖叫。当我执行程序时。它显示了以下内容:

*在“./a.out”中出错:munmap_chunk():无效指针:0x00007fa89f028d8a*

以及回溯和内存映射

下面是我的代码:

# include <stdio.h>
# include <gnu/libc-version.h>
# include <string.h>
# include <stdlib.h>

int main(void){
        const char *s;
        s = (const char *)malloc(16*sizeof(char));
        s = gnu_get_libc_version();
        printf("%s\n",s);
        free((char *)s);
        return 0;
}
#包括
#包括
#包括
#包括
内部主(空){
常量字符*s;
s=(常量字符*)malloc(16*sizeof(字符));
s=gnu_get_libc_version();
printf(“%s\n”,s);
自由((字符*)s);
返回0;
}

此函数
gnu get\u libc\u version()
可能返回指向静态内存的指针。

当您使用
gnu get\u libc\u version
的返回值重新初始化
s
时,您丢失了
malloc
返回的指针。您现在正试图
释放
gnu get_libc_version
返回的指针,该指针未被
malloc
分配

在调用
gnu get\u libc\u version
之前,您不需要
malloc
,也不需要在调用它之后
free

s = gnu_get_libc_version();
这并不像你想象的那样。看起来您希望它填充以前分配的内存,即
s
所指向的内存

它实际做的是使
s
指向完全不同的地方,这是由函数
gnu get\u libc\u version
决定的

给定
free
错误和中的示例用法,此内存不从堆中分配的可能性大于偶数,因此尝试释放它将导致未定义的行为

假设
gnu_get_libc_version
确实返回了一个C样式字符串的地址,并且它不是从堆中返回的(这显然是基于上面链接的情况),您不需要为它分配内存。相反,您只需:

int main(void) {
    const char *s = gnu_get_libc_version();
    printf("%s\n", s);
    return 0;
}
或者甚至更短(使用
直接输入
和返回值):

如果您确实希望将版本信息放入自己分配的缓冲区(并假设您有足够的内存),可以使用:

int main(void){
    const char *s = malloc(16);
    strcpy(s, gnu_get_libc_version());
    printf("%s\n", s); // or puts(s)
    free(s);
    return 0;
}
这会将字符串(从
gnu\u get\u libc\u version
返回的区域)复制到您自己的缓冲区中,而不是将
s
更改为指向其他地方


请注意,我已经更改了原始代码中的一些其他内容。第一个是删除
malloc
返回值的显式强制转换。这在C语言中是不应该做的,因为它可以隐藏某些细微的错误。C完全能够隐式地将
void*
返回值转换为另一个指针类型

第二个是免费的演员阵容,出于同样的原因,这也是不必要的

第三个也是最后一个更改是通过
sizeof(char)
删除乘法。该值由标准保证为
1
,因此不存在需要该值的技术原因。

s = gnu_get_libc_version();
您将
s
重新分配给另一个
char*
,该字符通过
gnu get\u libc\u version
返回。由于先前由
malloc
分配的
s
值丢失,导致内存泄漏。而且
malloc
没有分配
char*
通过
gnu get\u libc\u version
返回的
return,因此当您对
malloc
未返回的指针调用
free
时,会发生一些错误。
s=gnu_get_libc_version()

什么是“GNU版本号”?非洲的GNU有版本吗?不要在C中从
void*
转换到
free
在第9行中使用
void*
,而不是
char*
。您有内存泄漏,因为您分配的内存仍然存在,但您将其重新分配给gnu get_libc_version()。gnu_get_libc_版本为您返回一个指向字符串的常量指针。您试图释放不需要释放的内存(gnu_get_libc_版本),在动态内存指针之外的任何地方调用FREE都会导致它向您尖叫。提示,gnu_get_libc_版本的原型是
const char*gnu_get_libc_版本(void)注意const char*,它通常是一个提示,返回的字符串并不意味着要被释放。谢谢!我意识到这个问题有点愚蠢。即使没有,赋值也会覆盖指向已分配内存的指针。你是对的。此函数返回指向静态内存的指针。谢谢!你的回答非常全面和多方面。我学到了很多。
s = gnu_get_libc_version();