指针是否释放判断_C++|array new包含指针成员指向堆内存的类对象的内存管理细节

Classes 根据是否包含指针成员(指向动态内存(堆内存))可以分为:

Class without pointer member(s): complex

class complex{public:    complex (double r = 0, double i = 0): re (r), im (i) { }    complex& operator += (const complex&);    complex& operator -= (const complex&);    complex& operator *= (const complex&);    complex& operator /= (const complex&);    double real () const { return re; }    double imag () const { return im; }private:    double re, im;};

Class with pointer member(s): string

class String{public:                                    String(const char* cstr=0);                        String(const String& str);                       String& operator=(const String& str);         String::~String(){   delete[] m_data;}                                     char* get_c_str() const { return m_data; }private:   char* m_data;};

自然,对于包含有指针并使用了动态内存的类具有更高的复杂性,不能使用编译器默认提供的拷贝构造函数、拷贝赋值和析构函数,需要程序员自己重写。

对于类的对象自然也可以是栈对象,也可以是堆对象。

{    String s1("hello"); // 栈对象}// 当作用域结束时,自动调用~String()String *ps = new String("hello");delete ps;编译器自动转化为以下操作:String::~String(); //先调用析构函数,将对象中指针变量指向的空间释放掉operator delete(ps); //然后再释放自己所占的堆空间,底层调用的是C的free(ps)

对于包括有指针(指向堆内存)的堆对象,相当于使用了双重堆内存。

new的流程:

String *ps = new String("Hello");

编译器自动转化为以下操作:

String::~String();      // 先调用析构函数,将对象中指针变量指向的空间释放掉operator delete(ps); // 然后再释放自己所占的堆空间,底层调用的是C的free(ps)
485368c173f18cc7694971bd22b6f456.png

指针ps位于栈上(&ps),其值是一个堆内存地址。

调用构造函数String("Hello"),m_data指向"Hello":

c61ddcc25939b9aa3dbcc212552c1b61.png

delete流程:

delete ps;  // 手动释放

编译器自动转化为以下操作:

String::~String();      // 先调用析构函数,将对象中指针变量指向的空间释放掉operator delete(ps); // 然后再释放自己所占的堆空间,底层调用的是C的free(ps)
b1856f502c1ddea5301746590d0ad3c7.png

先~String();,然后:delete(ps);

1151489919bc06088c0e452e42c6b42e.png

arrary new:

b9547ac658c7ae01961d1f148bda0744.png

delete p:

17cb4fe2871c4679edaf8b894893bd4c.png

先~String(); 左边的一块堆内存释放掉了。

然后 delete(p); 右边的一块堆内存只释放掉了第一部分。

arrary delete: delete[] p :

e0265989c7c655cc77e838ce02a53cb2.png

先~String(); 左边的一块堆内存释放掉了。

然后 delete[] (p); 其中的[]就是告诉编译器,需要释放的是多份。

ref : C++面向对象高级编程(侯捷)

https://www.bilibili.com/video/BV14s411E772

-End-

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: auto_ptr是C++的一种智能指针,它可以在离开作用域后自动释放指向内存。如果auto_ptr指向的是一个数组,那么当auto_ptr离开作用域时,只会释放这个数组的第一个元素所占用的内存,而不会释放整个数组所占用的内存。 如果想要正确地删除这个数组,可以使用下面的代码: ```cpp #include <memory> int main() { std::auto_ptr<int[]> arr(new int[10]); // 用完 arr 后,使用 reset() 重新设置指针 arr.reset(new int[10]); return 0; } ``` 或者使用C++11的std::unique_ptr,它可以正确地释放数组所占用的内存: ```cpp #include <memory> int main() { std::unique_ptr<int[]> arr(new int[10]); // 用完 arr 后,直接将指针赋为 nullptr 即可 arr = nullptr; return 0; } ``` 如果你使用的是C++98标准或者更早的版本,可以使用std::auto_ptr的特殊版本std::auto_ptr_ref,它可以正确地释放数组所占用的内存。 ```cpp #include <memory> int main() { std::auto_ptr<int> arr(new int[10]); // 用完 arr 后,使用 reset() 重新设置指针 std::auto_ptr_ref<int> ref(arr); arr.reset(new int[10]); return 0; } ``` 但是,在C++11标准以后,std::auto_ptr已经被废弃了,所以更推荐使用std::unique ### 回答2: cpp中的auto_ptr是一个智能指针,用于管理动态分配的内存。如果auto_ptr指向的是一个数组,可以使用delete[]操作符来释放数组内存。 具体步骤如下: 1. 创建一个指向数组的auto_ptr对象,例如: auto_ptr<int> ptr(new int[5]); 2. 使用delete[]操作符来释放数组内存,例如: delete[] ptr.get(); 在这里,我们使用ptr对象的get()方法来获取指向数组的原始指针,并对该指针使用delete[]操作符进行删除。 需要注意的是,auto_ptr是C++98引入的智能指针,自C++11起被弃用。推荐使用更先进的智能指针如unique_ptr、shared_ptr等替代auto_ptr。 ### 回答3: 使用auto_ptr管理指向数组的指针是不安全的,因为auto_ptr会尝试使用delete操作符删除数据,而不是使用delete[]操作符。因此,当auto_ptr指向一个动态分配的数组时,调用delete操作符只会释放数组中的第一个元素,而不会释放整个数组。这可能导致内存泄漏和其他未定义的行为。 为了安全地删除指向数组的指针,可以考虑使用C++11中引入的智能指针unique_ptr或shared_ptr。这两种智能指针都支持通过delete[]来删除动态分配的数组。例如,在使用unique_ptr时,可以像下面这样删除数组: ```cpp std::unique_ptr<int[]> ptr(new int[5]); // 使用数组指针ptr操作数组 // ... ptr.reset(); // 删除整个数组 ``` 在上述代码中,使用unique_ptr创建了一个指向有5个int型元素的数组的指针,然后可以通过ptr指针进行数组操作。最后,使用reset函数删除整个数组。 总而言之,虽然auto_ptr可以管理指向单个对象的指针,但不适合用于管理指向数组的指针。在这种情况下,应该使用unique_ptr或shared_ptr来确保安全和正确地删除整个数组。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值