您如何安全地从内存中清除使用 new 关键字创建的对象(具有属性)?

How do you safely clear an object from memory (with attributes) which was created using the new keyword?

据我所知,每个“新”调用都需要对该对象进行相应的“删除”调用。那么这真的正确吗?:

using namespace std;

class Box {
   public:
      double length;
      char letters_in_box[80];
};

int main() {
   Box *b = new Box;
   b->length = 2.0;
   b->letters_in_box = "Hello world";

   //Some code with b

   delete b;

   return 0;
}

与“length”double 和“letters_in_box”数组关联的内存是否由此清除?

So is this really correct?

是的,没错。但是,您必须确保在删除 b.

之前不会抛出异常

例如:

Box *b = new Box;
b->length = 2.0;
b->letters_in_box = "Hello world";

throw 5; //this is not usually done.

delete b;

在此示例中,如果在调用delete之前未处理异常,则会发生memory leak

是的。当您删除 b 时,它也会删除 letters_in_box 数组。

但是,对于您的 b->letters_in_box = "Hello world";,您将得到一个编译错误:“错误 C3863:数组类型 'char [80]' 不可分配”

#include <memory> // For 'memcpy_s' (since C11)

class Box
{
public:
    double length;
    char letters_in_box[80];
};

int main()
{
    Box* b = new Box;

    b->length = 2.0;
    // b->letters_in_box = "Hello world"; ** Compile Error C3863: array type 'char [80]' is not assignable **
    memcpy_s(b->letters_in_box, sizeof(b->letters_in_box), "Hello world", sizeof("Hello world"));

    // Some code with b

    delete b;
}

现代 C++

new 更好的做法是 智能指针 ,例如,在出现异常的情况下,您根本不必费心删除:

#include <memory> // For 'std::unique_ptr' and for 'memcpy_s'

class Box
{
public:
    double length;
    char letters_in_box[80];
};

constexpr char my_text[] = "Hello world"; 

int main()
{
    auto b = std::make_unique<Box>(); // No need to delete

    b->length = 2.0;
    memcpy_s(b->letters_in_box, sizeof(b->letters_in_box), my_text, sizeof(my_text));

    // Some code with b
}

此外,(而不是 C 数组)我更喜欢使用 C++ 数组:

#include <array>  // For 'std::array'
#include <memory> // For 'std::unique_ptr' and for 'memcpy_s' 

class Box
{
public:
    double length;
    std::array<char, 80> letters_in_box;
};
   
constexpr char my_text[] = "Hello world";

int main()
{
    auto b = std::make_unique<Box>(); // No need to delete

    b->length = 2.0;
    memcpy_s(&b->letters_in_box, b->letters_in_box.size(), my_text, sizeof(my_text));

    //Some code with b
}

--

最后一条评论: 如果没有使用 char[] 的限制,我会改用 std::string

#include <string> // For 'std::string'
#include <memory> // For 'std::unique_ptr' 

class Box
{
public:
    double length;
    std::string letters_in_box;
};

int main()
{
    auto b = std::make_unique<Box>(); // No need to delete

    b->length = 2.0;
    b->letters_in_box = "Hello world";

    //Some code with b
}

在现代 C++ 中,强烈建议 不要 使用 new 和 delete,原因如 Karen 在上面提到的那样,如果在程序期间由于任何原因发生异常,并且您的异常处理导致一个分支不会 return 回到 运行 删除,然后这会导致内存泄漏。

相反,我会考虑使用智能指针 (https://en.cppreference.com/book/intro/smart_pointers) 来创建指向所用对象的新指针,因为一旦它们超出范围(唯一指针),这些将允许重新分配内存 (即异常分支后跟不 returning 到同一范围),或者一旦它们的 'references' 数量到期(共享指针)。

关于您编写​​的显式代码,是的,一旦 class 被删除,“length”double 和“letters_in_box”数组将被删除,但重要的是要注意如果您已显式使用 malloc/calloc/etc 分配内存,则应使用 class 析构函数来释放此内存。

编辑:还强烈推荐阅读 RAII (https://en.cppreference.com/w/cpp/language/raii),因为它确实是现代、安全的 C++ 的基础。