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

2019 年 4 月 26 日
 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 个字节的堆内存,创建了又销毁,不应该出问题才对啊。

大家有什么看法?

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

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

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

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

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

© 2021 V2EX