我有一些结构:
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;
}
我知道这远非理想,远未完成。但是我想知道我是否以正确的方式删除了我的记忆(请不要告诉我如何正确地做到这一点。我正在试图弄清楚自己)。
the link这是对我来说非常重要的不同问题。
答案 0 :(得分:4)
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会导致另一个析构函数调用不正确。你只需要释放内存。 e.g。
delete[] static_cast<char*>(p);
如果要分配原始内存以用于展示位置new
,则直接使用分配功能更为常规。 e.g。
void* p = ::operator new[](sizeof(A));
A* tmp = new (p) A("tmp");
tmp->~A();
::operator delete[](p);
考虑做一些更简单的事情。这个块可以用一个更稳健的局部变量替换。
A tmp("tmp");
答案 1 :(得分:2)
如果您使用p = new[…]
分配内存,那么您应该使用delete[] p
[1] 取消分配,没有例外。
不要在tmp
死后捣乱。
(Placement new不分配内存,析构函数不会修改new char[sizeof(A)]
,因此他们不会回答问题。)
[1]:您应将p
声明为char*
。或者将p
投射到char*
中的delete[]
。
答案 2 :(得分:0)
为A
的实例分配内存只需编写A* p = new A("tmp");
。它将分配内存并调用构造函数。然后使用delete p;
来调用析构函数并释放内存。我认为没有必要在您的案例中使用新的展示形式。
答案 3 :(得分:0)
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
}
答案 4 :(得分:0)
如果要为类中的指针分配内存,析构函数也应该释放(删除)内存:
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
。