new 出来的vector ,需不需要delete?

好好單调 2014-04-01 01:41:23
#include <vector>
#include <iostream>
using namespace std;

int i = 0;
int j = 0;

class CDemo{
public:
CDemo():str(NULL){
cout << "constructor:" << i++ << endl;
}

CDemo(const CDemo& cd)
{
cout << "copy constructor:" << i++ << endl;
this->str = new char[strlen(cd.str) + 1];
strcpy(this->str, cd.str);
}

~CDemo(){
cout << "destructor:" << j++ << endl;
if(str)
{
delete [] str;
str = NULL;
}
}

char* str;
};

void main()
{
CDemo d1;
d1.str = new char[32];
strcpy(d1.str, "trend micro");

vector<CDemo> *a1 = new vector<CDemo>();
a1->push_back(d1);
delete a1;
a1 = NULL;

getchar(); // 输入s

return;
}


上面是代码和运行结果,好奇怪new出来的a1在delete之后,main函数退出的时候似乎又执行了一次。哪位大大给我解释一下,谢谢啦。
...全文
2326 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Enockipp 2014-04-03
  • 打赏
  • 举报
回复
CDemo d1;执行构造函数 a1->push_back(d1);执行复制构造。 现在有两个对象,所以执行两次析够函数。 需要delete
CyberLogix 2014-04-02
  • 打赏
  • 举报
回复
new和delete必须匹配,除非你使用的是智能指针会自动释放
luciferisnotsatan 2014-04-02
  • 打赏
  • 举报
回复
你new的是vector,你delete的是vector,这个和CDemo没有任何关系。new是给vector这个结构体本身分配空间之后进vector的构造,delete也是析够vector结构体本身,释放空间。 CDemo d1;时调用了一次构造函数。 a1->push_back(d1); 因为你的 vector<CDemo>里放的是CDemo对象,而不是指针,然后进行了一次拷贝构造。push_back里的拷贝和赋值次数和push_back的具体实现有关,不一定就是一次拷贝构造。当发生扩展时,你可能见到很多拷贝构造和析够。 delete a1; 这个释放了vector,vector里面的对象生命期也就结束了。如果你用的是vector<CDemo*>,你需要手工一一释放里面的元素,不然就是指针生命期结束,而指向的对象没有delete。你需要: for(int i=0;i<a1.size();i++) {delete a1[i];} 退出main时,d1的生命期结束。
FrankHB1989 2014-04-02
  • 打赏
  • 举报
回复
引用 4 楼 luciferisnotsatan 的回复:
[quote=引用 2 楼 FrankHB1989 的回复:] [quote=引用 1 楼 luciferisnotsatan 的回复:] 有new就有delete
默认placement new呢。[/quote] placement new又不是用来申请内存的 用placement new之前,先要new/malloc一段内存吧,当然你也可以用栈上的。placement new对应的是手动调用析构函数 要这么说,还可以重载operator new [/quote] 对,还有重载的operator new。上面只是举例:没法一概而论。 至少字面上不分配存储的new还是符合“new出来的”。
引用 8 楼 OExpress 的回复:
new和delete必须匹配,除非你使用的是智能指针会自动释放
同理。
好好單调 2014-04-01
  • 打赏
  • 举报
回复
引用 1 楼 luciferisnotsatan 的回复:
有new就有delete
问题是这里竟然调用了两次析构。 这是我不明白的地方。
引用 3 楼 dbzhang800 的回复:
你贴出的结果很正常,delete也没有问题。因为你有两个CDemo对象
引用 5 楼 WORSTBOYZYM 的回复:
a1->push_back(d1); vector会拷贝一个CDemo delete的时候会调用这个CDemo的析构 main函数退出的时候d1这个局部变量当然要析构掉
这么说我就懂了。这个问题源自于下面这段代码的改错,原来因为没有提供拷贝构造函数,所以vector拷贝的对象没有进行深拷贝,所以释放了同一块内存两次,就出错了。 谢谢啦。
#include <vector>
#include <iostream>
using namespace std;

int i = 0;
int j = 0;

class CDemo{
public:
	CDemo():str(NULL){
		cout << "constructor:" << i++ << endl;
	}

	//CDemo(const CDemo& cd)
	//{
	//	cout << "copy constructor:" << i++ << endl;
	//	this->str = new char[strlen(cd.str) + 1];
	//	strcpy(this->str, cd.str);
	//}

	~CDemo(){
		cout << "destructor:" << j++ << endl;
		if(str)
		{
			delete [] str;
			str = NULL;
		}
	}

	char* str;
};

void main()
{
	CDemo d1;
	d1.str = new char[32];
	strcpy(d1.str, "trend micro");

	vector<CDemo> *a1 = new vector<CDemo>();
	a1->push_back(d1);
	delete a1;
	a1 = NULL;

	getchar(); // 输入s

	return;
}
WORSTBOYZYM 2014-04-01
  • 打赏
  • 举报
回复
a1->push_back(d1); vector会拷贝一个CDemo delete的时候会调用这个CDemo的析构 main函数退出的时候d1这个局部变量当然要析构掉
luciferisnotsatan 2014-04-01
  • 打赏
  • 举报
回复
引用 2 楼 FrankHB1989 的回复:
[quote=引用 1 楼 luciferisnotsatan 的回复:] 有new就有delete
默认placement new呢。[/quote] placement new又不是用来申请内存的 用placement new之前,先要new/malloc一段内存吧,当然你也可以用栈上的。placement new对应的是手动调用析构函数 要这么说,还可以重载operator new
dbzhang800 2014-04-01
  • 打赏
  • 举报
回复
你贴出的结果很正常,delete也没有问题。因为你有两个CDemo对象
FrankHB1989 2014-04-01
  • 打赏
  • 举报
回复
引用 1 楼 luciferisnotsatan 的回复:
有new就有delete
默认placement new呢。
luciferisnotsatan 2014-04-01
  • 打赏
  • 举报
回复
有new就有delete

65,208

社区成员

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

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