【问题标题】:Allocate and Delete memory for pointers in a struct C++为结构 C++ 中的指针分配和删除内存
【发布时间】:2015-02-13 09:40:27
【问题描述】:

给定以下结构声明:

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 不会改变指针指向的地址。
  • 始终匹配 new -> deletenew[] -> delete[]deleteing 某些东西不会神奇地将指针设置为 null,如果它对您的程序很重要,您将不得不自己做。旁注:不要使用newdelete
  • user657267 在他的旁注中可能的意思是,除非您是 C++ 学生,否则您应该更喜欢使用 C++11 工具,例如 std::unique_ptrstd::shared_ptr,或者,当然, 堆栈分配。

标签: c++ pointers dynamic-allocation


【解决方案1】:

应该是这样的

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

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

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

#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++ 学生,我必须使用 cstrings 和动态分配来进行学习。所以我做'cout test;' 执行此操作时值保持不变。为什么?
  • 假设您的意思是,例如,newObject-&gt;testdelete newObject 之后发生了变化,那么可能会发生很多事情 -- newObject-&gt;test 在@ 之后是无效的987654334@ 是 deleted,你不能指望它有任何价值。 在可能导致这种明显变化的事情中:如果你正在使用 Visual Studio,调试堆的释放例程会覆盖使用0xfeeefeee 释放内存以使其可识别。让我再次强调,这是不可靠的,这样的代码可能会崩溃或做任何其他事情。
【解决方案2】:

如果你使用 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 时,将自动调用结构内部指针上的删除。

请记住,使用删除不会删除任何数据!它只是释放使用过的内存——比如“嘿,我不再使用这部分内存了”,所以它可以被其他一些数据使用。使用完某个指针后,必须始终使用delete,否则会发生内存泄漏。

【讨论】:

    【解决方案3】:

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

    // 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

    由于析构函数不能保证成员确实以这种方式分配,因此最好将分配成员的责任也传递给结构的成员函数或构造函数。

    【讨论】:

      【解决方案4】:

      正如 cmets 中所说,delete 只是释放内存,它不会更改指针指向的地址。如果不想自己分配/释放内存,推荐smart pointers

      【讨论】:

        猜你喜欢
        • 2014-02-23
        • 1970-01-01
        • 2019-09-17
        • 2019-09-23
        • 1970-01-01
        • 2023-04-02
        • 2017-01-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多