C 语言 free()函数的问题

2019-06-11 23:57:13 +08:00
 africwildman

如下代码:

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

int main()
{
    char *a=(char *)malloc(5*sizeof(char));
    char *b=(char *)malloc(5*sizeof(char));
    a="1234";
    b="5678";
    printf("%s\n",a);
    printf("%s\n",b);
    free(a);
    free(b);
    return 0;
}

运行时显示错误:free(): invalid pointer

a 和 b 互不相干,为什么就 free 出问题了呢?

4008 次点击
所在节点    C
19 条回复
huaouo
2019-06-12 00:00:17 +08:00
因为 free 的不是 malloc 出来的堆上的地址,而是"1234", "5678"这两个字符串字面值的地址。
Nitroethane
2019-06-12 00:01:48 +08:00
"1234" 和 "5678" 是字符串字面量,是保存在可执行二进制文件里面的
byteli
2019-06-12 00:01:49 +08:00
很久不写 c 猜测下,是 a= b=造成的隐式转换吧,要用*a= *b=
creamiced
2019-06-12 00:04:15 +08:00
赋值方式有问题,可以使用类似 strcpy(a,"1234")
a="1234"之后,a 已经不再指向 malloc 出来的内存,而是指向 1234 这个字符串常量的地址了
africwildman
2019-06-12 00:06:47 +08:00
@huaouo
@Nitroethane
@creamiced
哦,明白了,我赋值方式不对。
PanPancf
2019-06-12 00:07:44 +08:00
free 错了,还导致了 memory leak。。你的本意应该要 strcpy
elfive
2019-06-12 06:37:12 +08:00
对 char*的赋值就错了……你要用 strcpy 或 memcpy 去给它赋值成其他字符串的……
tamlok
2019-06-12 08:50:15 +08:00
建议再认真看看 c 教材。。。
zycpp
2019-06-12 09:18:02 +08:00
哈哈哈,跟我以前一样
ps:sprintf 也能赋值字符串
testeststs
2019-06-12 10:18:00 +08:00
a="1234";
这个你不会以为是拷贝吧。
haozhang
2019-06-12 10:28:53 +08:00
a="1234" 这一句就是错的,“ 1234 ”是 const char *,而 a 是 char *,按照理论上,你无法把一个 const char *赋值给 char *,你这个就编译不过去。
haozhang
2019-06-12 10:32:50 +08:00
“ 1234 ”这个是字符串常量,存放在堆上面的,内存的开辟释放都是由汇编写死的,不需要你去 free,a=1234,相当于把 1234 的存放的内存地址赋值给 a,但这么做是非法的,因为 a 是 char*,1234 是由一个 const char *指向的,你无法把一个 const char *赋值给 char *变量
zwh2698
2019-06-12 11:07:26 +08:00
大侠,看到你的标题我吓到了,看到代码,我想说看看谭浩强的书,不用求人。
skx926
2019-06-12 11:44:13 +08:00
@haozhang 常量不应该在常量区吗,怎么会在堆上
haozhang
2019-06-12 12:10:05 +08:00
@skx926 恩,是存在常量区,我说错了
tomychen
2019-06-12 13:06:01 +08:00
@zwh2698 哈哈,,,我怎么觉得你这回复那么可爱
oaix
2019-06-12 14:06:55 +08:00
不要使用 strcpy,使用带长度参数的 strncpy
wisefree
2019-06-12 15:43:00 +08:00
@haozhang 题主问的是 C 语言,不是 C++

``` c
#include <stdio.h>

int main(void)
{
char *s = NULL;
s = "1234"; // C 语言中不会报错
printf("%s\n", s);

return 0;
}

```
haozhang
2019-06-12 15:59:30 +08:00
@wisefree c 也会报错的啊,c11 之后这个 char *str = “ 123 ”,就已经不能写了,c11 之前就算你写了有也不能用 str[0] = ’ 6 ’ 这种去修改 read only 的东西,会报 runtime error 的,你可以用版本高一点的 gcc 试试。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/572991

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX