C++ 函数delete 问题;
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ 函数delete 问题;相关的知识,希望对你有一定的参考价值。
#include <iostream>
using namespace std;
class cmessage
public:
cmessage(char* g)
int i=strlen(g)+1;
f=new char[i];
strcpy(f,g);
~cmessage()
cout<<"called the destructor"<<endl;
delete []f;
private:
char *f;
;
void messfun(cmessage f)
return;
int main()
cmessage g("lisng laiye");
messfun(g);
return 0;
添加了 delete [] f; 运行时就弹出终止的窗口 请问路高手这是咋回事捏
我把delete [] f ; 去掉
然后在messfun(g);后面添加 g.show()以显示f指向的字符串 结果运行成功了 依你说析构函数不是已经将f调用delete[]删掉了吗
好吧是我表述不清……
messfun函数返回时,调用析构函数,【析构函数】内部执行delete []f;释放参数 f 的成员变量 f 指向的内存空间,而这时候g指向的是同样的空间,因此main函数返回的时候调用析构函数销毁 g的时候delete []运算符释放的是已经释放过的的空间……
删掉析构函数中的delete [] f ; 则两次delete []都不存在,留下则两次都存在……
刚才没看清楚 不过现在好像明白了
呢能告诉我 如果 "两次delete []都不存"
该怎样去掉动态分配的内存呢
不使用默认的复制构造函数,而定义自己的复制构造函数,使复制构造之后 f 和 g 的成员指针指向不同的地址大概是最好的办法……
如果一定要让两个cmessage对象的成员指针指向相同的地方,也可以使用标准头文件中的智能指针shared_ptr来管理内存,虽然shared_ptr是新标准才有的东西,不过大多数较新的编译器应该都支持……
调用 messfun时 调用了默认的拷贝构造函数 ,该函数依次对所有成员进行一次拷贝操作,所以你的 f被释放了两次。 参考技术B
delete[] 是delete一个数组,指针不需要加[]
当把g传递给messfun时,实际执行的是 cmessage f = g; 只是简单的把g.f复制给f.f,但是却指向同一块内存,所以当函数结束时调用一次析构,释放堆内存,当main函数结束时又调用一次析构,又再次释放,此时发现要被释放的内存不存在了,所以报错,double free.重载operator=运算符即可.
C++中delete与 delete []区别
new调用构造函数,delete会调用对象的析构函数。
malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。
delete只会调用一次析构函数,而delete[]会调用每一个数组元素的析构函数。
在More Effective C++中有更为详细的解释:“当delete操作符用于数组时,它为每个数组元素调用析构函数,然后调用operator delete来释放内存。”
delete与new配套,delete []与new []配套。
VC6 新建一个单文档工程;
加入一个普通类;名字为T;
加入后如下;
在构造和析构函数各加入一句代码;
添加一个菜单;菜单处理函数如下;
void CDeltestView::OnMenuitem32771()
// TODO: Add your command handler code here
const int NUM = 3;
CString str1;
T* p1 = new T[NUM];
//cout << hex << p1 << endl;
// delete[] p1;
str1.Format("p1: %x",p1);
AfxMessageBox(str1);
delete p1;
T* p2 = new T[NUM];
//cout << p2 << endl;
str1.Format("p2: %x",p2);
AfxMessageBox(str1);
delete[] p2;
点击菜单;运行到第一段代码时;
弹出3次 构造;
然后显示p1的值;
之后弹出一次 析构;
运行到第二段代码时;也是先弹出3次 构造;
然后弹出显示p2的值;
然后弹出了3次 析构;
以上是关于C++ 函数delete 问题;的主要内容,如果未能解决你的问题,请参考以下文章