一段神奇的 C++代码,大家觉得有没有问题?

2019-04-26 16:15:01 +08:00
 Wangjl

如下代码,我在 vs2015 中,for 循环 1000 遍,没有问题,10000 遍就报错

大家觉得是哪里的问题呢?

#include <stdio.h>

void f(char* p)
{
	delete[] p;
	p = new char[20000];
}

int main()
{
	
	for (int i = 0; i < 10000; i++)
	{
		char *p = new char[2];
		f(p);
		delete[] p;
	}
	getchar();
	return 0;
}

按理说以上代码只是在循环创建 20000 个字节的堆内存,创建了又销毁,不应该出问题才对啊。

大家有什么看法?

7243 次点击
所在节点    C
55 条回复
wutiantong
2019-04-26 16:18:05 +08:00
你 f 里面分配的 20000 字节从未释放过
wutiantong
2019-04-26 16:18:55 +08:00
别以为名字都叫 p 的就是同一个变量了。。。
kizunai
2019-04-26 16:19:46 +08:00
楼上正解
downdowndown30
2019-04-26 16:20:38 +08:00
@wutiantong 那 for 循环里的 delete 干了什么?
lhx2008
2019-04-26 16:20:42 +08:00
我猜一下,f 的时候指针复制了一份,所以你把 char[2]删除了,但是出了 f 函数,旧的 p 指向的地址不变
Wangjl
2019-04-26 16:20:45 +08:00
@wutiantong 为什么呢? 我 p 用的是指针啊,而且我调试的时候,看内存发现确实被释放掉了啊
downdowndown30
2019-04-26 16:21:25 +08:00
@wutiantong 哦。。。明白了,感谢
linxiaoziruo
2019-04-26 16:21:34 +08:00
引用传递和值传递
superzou
2019-04-26 16:23:02 +08:00
f 函数里面 p 一直都没有释放过。
downdowndown30
2019-04-26 16:24:35 +08:00
@Wangjl 你看看 f 里的 p 和 for 里的 p 在栈里是不是同一个对象
wutiantong
2019-04-26 16:25:12 +08:00
@downdowndown30 那个 delete 操作了“野指针”,严格来说是 UB 了
maxco292
2019-04-26 16:26:51 +08:00
正确做法:void f(char*& p)
Wangjl
2019-04-26 16:30:31 +08:00
搞不懂了,我 vs 里跟踪的时候,发现在 for 循环里的 p 遍历的地址,和 f 函数里,重新分配的地址是一样的。
bb123
2019-04-26 16:33:11 +08:00
1.double free
2.值传递与指针传递
wutiantong
2019-04-26 16:36:14 +08:00
@Wangjl 重新分配的地址一样没什么好奇怪的,它可能会一样也可能会不一样,一样的时候就无事发生,不一样的时候程序就可能会挂掉。
GPIO
2019-04-26 16:36:55 +08:00
值传递都是拷贝一份再操作的
Wangjl
2019-04-26 16:39:55 +08:00
懂了,感谢各位的回复。 这让我这个初学者难了好久,一直想不通。现在经各位指点已经想通了,应该用引用,否则会变成值传递。 造成二次释放。c++真的感觉比其他语言好难啊,坑比较多哦。
dfjslkjdf
2019-04-26 16:43:20 +08:00
@wutiantong
大哥好眼力
Wangjl
2019-04-26 16:45:03 +08:00
402124773
2019-04-26 17:04:44 +08:00
学一下智能指针

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

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

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

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

© 2021 V2EX