为结构C++中的指针分配和删除内存

Allocate and Delete memory for pointers in a struct C++

给定以下结构声明:

struct Student

{

   char *     name;
   int  *     test;
   float      gpa;

};

int main() {

Student *newObject = new Student;

newObject->name = new char[10];
newObject->test = new int;

return 0;
}

我的问题是如何销毁创建的动态变量? 我尝试了 delete newObject->name;delete newObject->test; 但它似乎不起作用,因为它向我显示了与之前相同的地址 delete 。使用 delete newObject; newObject = nullptr; 删除对象就够了吗?

正如评论中所说,delete只是释放内存,它不会改变指针指向的地址。如果您不想自己分配/释放内存,请选择 smart pointers.

应该是

delete[] newObject->name;
delete newObject->test;
delete newObject;

因为name分配了new[],而另外两个分配了newdeletedelete[] 都没有改变指针值,但是,它只是使指针过去指向的内容无效。

但是,这样做是相当糟糕的。对于对象本身和 int,根本没有理由使用动态分配,对于 name,标准库中有一个名为 std::string 的 class为您进行内存管理。最好将代码替换为

#include <string>

struct Student {
  std::string name;
  int         test;
  float       gpa;
};

int main() {
  Student newObject;

  // do stuff, for example
  newObject.name = "John Doe";
  newObject.test = 123;
  newObject.gpa  = 3.1415926;

  // no manual cleanup necessary; it happens automatically when
  // newObject goes out of scope.
  return 0;
}

如果您使用的是 C++,则应该在您的结构中使用构造函数和析构函数(除非您真的需要 POD 类型的结构)。

struct Student
{
    Student(){
        name = new char[10];
        test = new int;
    }
    ~Student(){
        delete[] name;
        delete test;
    }
    char *     name;
    int  *     test;
    float      gpa;

};

int main() {
    Student *newObject = new Student;
    delete newObject;
    return 0;
}

当您在 newObject.

上使用 delete 时,将自动调用结构内部指针的删除

请记住,使用删除不会删除任何数据!它只是释放使用过的内存——比如"Hey, I'm not using this part of memory anymore",所以它可以被其他一些数据使用。当你用完一些指针时,你必须总是使用 delete,否则你会发生内存泄漏。

简短的回答是您确实需要在每个成员指针上使用 deletedelete [](视情况而定)。正如 remyabel 评论的那样,删除不会更改指针的值,它只是释放该指针所指的内存。

// delete dynamically constructed members
delete newObject->test;
delete[] newObject->name;

new 的实现可能会以不同于单个项目的数组分配内存的方式分配内存,因此在删除前者时使用 delete []delete 为以后。

处理清理的更惯用的方法是在结构 Student 的析构函数中执行这些删除。为了安全起见,在构造时使用空指针分配和构造或初始化成员(空指针上的delete不执行任何操作。)

struct Student
{
    char *   name;
    int  *   test;
    float    gpa;

    Student(): name(0), test(0), gpa(0.0f) {}

    ~Student() {
        delete[] name;
        delete test;
    }
};

delete newObject 将依次正确删除分配的成员,前提是它们确实分配了 new[]new.

因为析构函数不能保证成员确实是这样分配的,所以最好将分配成员的责任也传递给结构的成员函数或构造函数。