覆盖用new关键字c ++初始化的变量

时间:2013-11-19 15:13:32

标签: c++ new-operator delete-operator

如果我这样做:

void foo() {
  bar* b2 = new bar();
  b2 = new bar();
}

使用new初始化的第一个柱值会发生什么变化?它被第二个赋值覆盖了,还是应该事先使用delete关键字删除?

5 个答案:

答案 0 :(得分:4)

这是内存泄漏。 C ++已经为你的对象分配了空间,然后你丢失了对它的所有引用,所以它会在那里停留,因为你的程序运行时其余部分都没用,而且空间很大。

这就是为什么在C ++中它通常首选来使用new

void foo() {
  bar b2 = bar();
  b2 = bar();
}

特别是在你只想在1个范围内使用变量的情况下,在堆栈上分配它是一个更安全的选择。特别是在例外的情况下,

Foo foo = new Foo();
...
delete foo;

是不安全的,如果...抛出异常怎么办?你漏了!如果你想要C ++ 11中的安全和指针语义

unique_ptr<bar> b2;

如果你真的想要指针语义。现在,当b2的所有引用都丢失时,它将自行删除。注意:循环仍然没有破裂和泄漏。

答案 1 :(得分:3)

在为delete分配新值之前,您应该为第一个b2致电b2。第二个调用确实会覆盖b2中的值(这是在第一个new中创建的对象的地址)。

换句话说,您的代码有内存泄漏,因为第一个bar对象“丢失”。

答案 2 :(得分:0)

如果您使用new创建内容,则必须使用delete将其释放,否则会出现内存泄漏。 为了防止泄漏,你应该写:

void foo() {
  bar* b2 = new bar();
  delete b2;
  b2 = new bar();
}

答案 3 :(得分:0)

你的第一行:

bar* b2 = new bar()将在免费存储上分配sizeof(bar)空间(并且还调用构造函数)并给出该单元的地址,比如说它是0x123,这意味着b2会记住0x123。

但是现在你覆盖你的b2 - 它现在指向一个新的位置给你的新位置。这意味着您无法再访问第一次新呼叫分配的旧内存单元。

答案 4 :(得分:0)

你的第一行有三件事要做。

  1. 定义bar *,
  2. 类型的变量b2
  3. 使用new运算符
  4. 在堆上分配一个bar对象
  5. 将结果2分配给1
  6. 中定义的变量

    考虑到这种分离,很明显你为一个变量赋值两次。由于您需要此变量来删除在覆盖第一个指定值后丢失的对象。这是“内存泄漏”的一种情况。

    在覆盖变量b2之前,您应该考虑类bar的对象的第一个实例。如果不再需要,请使用delete删除对象。如果仍然需要它,请复制指针。