2

我有这个 C++ 类:

class test{

    char* p;
    SomeClass* someObject;

   test(){
      ...
      p = (char*) malloc(1000);
      someObject = new SomeClass();
      ...
   }

   ~test(){}

}

我是否需要在测试析构函数中调用free(p)delete someObject显式调用以释放其分配的内存或该内存会自动释放?

4

5 回答 5

8

您需要释放析构函数中所有动态分配的内存。这不会自动完成。

您的类包含两个指针,并且基本上无法控制这些指向的内容。事实上,这些可能指向您不允许删除的对象,例如:

struct Foo {};
struct Bar {
  Foo* f_;
  Foo(Foo* f) : f(f_) {}
};

int main() {
  Foo f;
  Bas b(&f); // b has a Foo ptr, but should it delete it?
}

所以你可以看到自动删除指针数据成员并没有什么意义。

作为一般规则,如果您的班级管理资源1,那么您应该注意副本构建和分配;这意味着,如果这对类有意义,您应该禁用它们,或者为它们提供实现,因为编译器生成的那些不起作用。有关此主题的详细讨论,请参阅三的规则,以及有关 stackoverflow 的广泛讨论:

如果您不遵循此规则,那么默认的复制构造函数和赋值操作将进行浅拷贝,并且您将拥有多个实例具有指向相同动态分配对象的指针,它们都会在销毁时尝试删除。

您可以避免手动删除new使用智能指针创建的对象。在您的情况下,该类显然拥有动态分配的对象,您应该查看 C++11 的std::unique_ptrboost::scoped_ptr

最后,除非您真的需要,否则您可以通过完全避免指针来真正避免所有内存管理问题。您可以将您char*的替换std::string为例如:

class test{

    std::string p;
    SomeClass someObject;
    //test() : someObject() {} // default construction is probably OK...
};

1.即分配和释放内存,或者打开和关闭网络连接,或者创建和销毁互斥体等等。

于 2012-07-02T05:54:55.823 回答
3

是的,你必须拥有free任何你mallocdelete你的一切new

您也可以通过不在类中存储指针来避免这种情况。

class test{
public:
    std::string   p;
    SomeClass     someObject;
};
于 2012-07-02T06:07:06.093 回答
1

是的,你需要。如果你不想要,你可以使用智能指针

于 2012-07-02T05:57:17.397 回答
0

test如果在实例被破坏时不回收内存,则内存在技术上会泄漏。您可以改用智能指针来避免在析构函数中调用free或显式调用。delete

struct Free { void operator () (void *p) const { free(p); } };

class test {
    std::unique_ptr<char, Free> p;
    std::unique_ptr<SomeClass> someObject;
    test () : p(static_cast<char *>(malloc(1000)),
              someObject(new SomeClass)
    { //...
    }
    ~test () {}
};

这使用智能指针的析构函数为您执行清理操作。

如果test仅用作const全局实例,那么实现清理就不太重要了,因为在执行结束之前不会回收内存。但始终实施清理是一种很好的做法,因为它会使代码现在正确,并且test将来可能会以不同的方式使用。

于 2012-07-02T06:07:38.833 回答
0

是的,您需要明确地释放它们。指针作为数据类型没有任何析构函数。编译器/执行环境无法猜测指针是否指向任何有意义的东西。即使该值是有意义的,它也可能指向某个静态对象,例如。或者它可以指向更大对象的某个领域。编译器不会对指针进行任何自动清理。

于 2012-07-02T05:55:51.487 回答