繁体   English   中英

我是否正确删除了这个?

[英]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_;
  }
};

我强烈建议:

  1. 使用std::string而不是char *作为文本。
  2. 将链接移动到基类(首选项是使用模板作为节点的数据部分。}

基类将允许您使节点适应不同的数据类型:

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::mapstd::list

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM