[英]Am I deleting this properly?
我有一些结构:
struct A
{
const char* name_;
A* left_;
A* right_;
A(const char* name):name_(name),
left_(nullptr),
right_(nullptr){}
A(const A&);
//A(const A*);//ToDo
A& operator=(const A&);
~A()
{
/*ToDo*/
};
};
/*Just to compile*/
A& A::operator=(const A& pattern)
{
//check for self-assignment
if (this != &pattern)
{
void* p = new char[sizeof(A)];
}
return *this;
}
A::A(const A& pat)
{
void* p = new char[sizeof(A)];
A* tmp = new (p) A("tmp");
tmp->~A();
delete tmp;//I WONDER IF HERE I SHOULD USE DIFFERENT delete[]?
}
int _tmain(int argc, _TCHAR* argv[])
{
A a("a");
A b = a;
cin.get();
return 0;
}
我知道这远非理想,远未完成。 但我想知道我是否以正确的方式删除了我的记忆(请不要告诉我如何正确地做到这一点。我正试图弄清楚自己)。
这是对不同问题的链接 ,这对我来说非常重要。
void* p = new char[sizeof(A)];
A* tmp = new (p) A("tmp");
tmp->~A();
delete tmp;//I WONDER IF HERE I SHOULD USE DIFFERENT delete[]?
不。您已经调用了析构函数,因此调用delete会导致另一个析构函数调用不正确。 你只需要释放内存。 例如
delete[] static_cast<char*>(p);
如果你是用放置使用分配原始内存new
更传统的直接使用分配的功能。 例如
void* p = ::operator new[](sizeof(A));
A* tmp = new (p) A("tmp");
tmp->~A();
::operator delete[](p);
但考虑做一些更简单的事情。 该块可以用单个局部变量替换,该变量更加健壮。
A tmp("tmp");
如果你用p = new[…]
分配内存,那么你应该用delete[] p
[1]解除分配,没有例外。
它死后不要乱用tmp
。
(Placement new不分配内存,析构函数不会修改new char[sizeof(A)]
,因此它们不会输入问题。)
[1]:你应该将p
声明为char*
。 或者将p
转换为delete[]
的char*
。
为A
实例分配内存只需写A* p = new A("tmp");
。 它将分配内存并调用构造函数。 然后使用delete p;
调用析构函数并释放内存。 在您的案例中,我看不出是否需要使用新的展示形式。
A::A(const A& pat)
{
void* p = new char[sizeof(A)];
A* tmp = new (p) A("tmp");
tmp->~A();
delete tmp;//I WONDER IF HERE I SHOULD USE DIFFERENT delete[]?
}
是的,您应该使用delete [],因为您使用new []创建了内存。 此外,在到达构造函数(在本例中为复制构造函数)之前,已经分配了内存,因此不需要再次分配它,这就是您在此处尝试执行的操作。
删除对象时,会自动调用析构函数(在本例中为~A),因此除非您使用的是新的展示位置,否则无需显式调用它。 因此,删除中不需要显式删除为对象本身分配的内存,仅适用于它拥有的成员。
复制构造函数应该只是复制正在复制的东西中的重要信息。 最后,这里的代码采用字符串: A a("a");
,所以你需要一个字符串构造函数才能进行调用:
A::A(const std::string& name)
{
//Do stuff
}
如果要为类中的指针分配内存,析构函数也应该释放(删除)内存:
class Node
{
char * name_;
Node * p_left;
Node * p_right;
Node(const char * new_name)
: name_(NULL), p_left(NULL), p_right(NULL)
{
size_t size = strlen(new_name);
name_ = new char [size + 1]; // + 1 for terminating null
}
~Node()
{
delete[] name_;
}
};
我强烈建议:
std::string
而不是char *
作为文本。 基类将允许您使节点适应不同的数据类型:
struct Node
{
Node * p_left;
Node * p_right;
};
struct Name_Node
: public Node
{
std::string name;
};
struct Integer_Node
: public Node
{
int value;
};
OTOH,你可能想在这个练习后使用std::map
或std::list
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.