C 自由函数失败
我正在用Linux编写一个简单的程序。其目的是显示GNU版本号。但是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
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();