多线程中delete为啥指针还能用

liuduo251 2016-01-12 10:39:52
加精
本菜鸟发现一个让我很纠结的问题,还望各路大神出来指点小弟。明明在线程中delete了,但还是能调用,谁能告诉我为啥?该怎么避免?

#include <iostream>
#include <thread>
#include <list>
using namespace std;

class CTest
{
public:
CTest(){printf("%s [%p]\r\n","构造函数",(void*)this);}
~CTest(){printf("%s [%p]\r\n","析构函数",(void*)this);}
void Printf(char *sMsg){printf("%s [%p]\r\n",sMsg,(void*)this);}
};
std::list<CTest*>g_TestList;
void ThreadPro()
{
int nCount = 5;
while (nCount--)
{
if (g_TestList.size())
{
CTest *pTest = g_TestList.front();
g_TestList.pop_front();
pTest->Printf("ThreadPro test1");
delete pTest;
pTest->Printf("ThreadPro test2");
pTest = nullptr;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
int main()
{
CTest *pTest = new CTest;
printf("%s [%p]\r\n","main test1",&pTest);
g_TestList.push_back(pTest);
std::thread th = std::thread(ThreadPro);
th.join();

pTest->Printf("main test2");
printf("%s [%p]\r\n","main test3",&pTest);
}
...全文
2351 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
miao420906189 2016-01-20
  • 打赏
  • 举报
回复
Print里没有访问任何成员变量,也就是他并没有访问任何非法内存。
猴头 2016-01-20
  • 打赏
  • 举报
回复
这是 c++的基础理论知识......
一苇渡江694 2016-01-19
  • 打赏
  • 举报
回复
强烈推荐使用C++11的智能指针。 是C++11的普及使得C++这门古老、被人诟病最多的语言重新焕发了活力。
忘世麒麟 2016-01-19
  • 打赏
  • 举报
回复
引用 9 楼 rogone 的回复:
从前有个拆了引信的地雷,怎么玩都没事,没曾想突然炸了。 你发现的这个现象叫野指针,如果你以后从事c/c++开发,你将会发现99%的痛苦都来自于它。
野引信
伊顺鸣 2016-01-18
  • 打赏
  • 举报
回复
encoderlee 版主 2016-01-15
  • 打赏
  • 举报
回复
CTest类并没有数据成员,即便你把内存释放了,也没有出错,因为它不涉及内存的访问,即使你用空指针来调用它的成员函数都不会出错。但这明显是错误的用法,在平时编程中注意避免即可。至于如何避免,不复杂的程序肉眼都可以发现,复杂的程序中,可以遵循谁分配谁释放原则,或用智能指针来避免。
wweerxx 2016-01-15
  • 打赏
  • 举报
回复
释放完记得赋空。
wweerxx 2016-01-15
  • 打赏
  • 举报
回复
g_TestList.push_back(pTest);改为 g_TestList.push_back(&pTest);试试。
kuba110 2016-01-15
  • 打赏
  • 举报
回复
delete 只是标记 这块内存可以再次被程序分配出去 内容并不会清空 或改变 (因为这样做 影响执行效率), 如果程序没有申请新的空间 ,或 分配器没把空间分配出去 这时候 这个指针 或变量 是仍然可用的, 但 不要这样使用,因为 你并不知道 这个地方什么时候被分配出去,所以 结果是未知的。
赵4老师 2016-01-15
  • 打赏
  • 举报
回复
new和delete 相当于 借和还 不相当于 创建和销毁
fefe82 2016-01-14
  • 打赏
  • 举报
回复
这是要靠你来避免的。
zhouxiaofeng1021 2016-01-14
  • 打赏
  • 举报
回复
指针就像某种型号房间万能钥匙 new 就像 被分配到了房间 delete 就像将房间归还 万能钥匙还是可以指向其他地址,可以打开其他 同型号的房间 不知道 我这比喻 你明白了点没~~~ 指针呀 他只是指向被分配出来的内存 而不就是该地址
wq327 2016-01-14
  • 打赏
  • 举报
回复
delete只是告诉编译器,我不用了这块内存,这块内存你可以分给其他人用了,但是在其他人没用之前,这块内存保存的东西还是你原来使用的东西。所以只要你知道这块地址的地址,那么你照样可以用它,只是这样用存在安全隐患,因为你不知道这块内存是否存有其它人用的东西而已。知道为什么我们用内存的时候需要开辟内存并且进行初始化吗?因为我们需要开辟的内存也是编译器为我们开辟的安全内存(你free掉的内存就是安全内存 )。能用是很正常的,至于你用了之后会出现什么错误,那就不能无从可知了
liufuda 2016-01-13
  • 打赏
  • 举报
回复
你在38行加入个几秒的延时就不一样了。
qq120848369 2016-01-13
  • 打赏
  • 举报
回复
多线程共享对象,需要引用计数技术来保持资源可用,不需要显式的delete。
赵4老师 2016-01-12
  • 打赏
  • 举报
回复
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。
paschen 版主 2016-01-12
  • 打赏
  • 举报
回复
delete只是告诉说:这块内存我不用了,你可以分配给别人(同时上面的数据在被其他数据覆盖前,不会清0) 而不是说:这块内存不能用了 也就是说,你使用delete后的内存是不安全的,行为也是不确定的 虽然你看似可以用,但在上面的数据被其他数据覆盖时,你取到的就不正确了,如果你对这块内存进行写入,可能破坏了其他的有用数据
爆豆 2016-01-12
  • 打赏
  • 举报
回复
new之后的资源被两处指针(一个在main,另一个在thread_proc)一齐指向,一处delete,清空了;另外一处根本不知道有这个事件,指向还是有效的;都是个路牌,把一个拆了,另一个又没拆,当然能用嘛,管它指的是对还是未知
ztenv 版主 2016-01-12
  • 打赏
  • 举报
回复
引用 2 楼 liuduo251 的回复:
我已经置空了,给指针pTest = nullptr; 按道理是该指针没法再用了
引用 1 楼 lianshaohua 的回复:
那块内存还没有被申请做其他用途,还是空闲的,所以你可以操作;你可以试试在delete后再多申请些内存,有可能会出错了
你没有把pTest置空呀,你置空的只是push到list<>中的副本而已
liuduo251 2016-01-12
  • 打赏
  • 举报
回复
这样依然能过去,这到底是咋回事!

#include <iostream>
#include <thread>
#include <list>
using namespace std;

class CTest
{
public:
	CTest(){printf("%s [%p]\r\n","构造函数",(void*)this);}
	~CTest(){printf("%s [%p]\r\n","析构函数",(void*)this);}
	void Printf(char *sMsg){printf("%s [%p]\r\n",sMsg,(void*)this);}
};

void ThreadPro(CTest *pTest)
{
	int nCount = 5;
	while (nCount--)
	{
		pTest->Printf("ThreadPro test");
	}
	delete pTest;
}
int main()
{
	CTest *pTest = new CTest;

	std::thread *pth = new std::thread(ThreadPro,pTest);
	pth->join();
	delete pth;

	pTest->Printf("main test2");
	printf("%s [%p]\r\n","main test3",&pTest);
}
加载更多回复(4)

64,645

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧