微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

对象数组是存储在堆栈中还是堆中?

如何解决对象数组是存储在堆栈中还是堆中?

在以下代码中:

#include <iostream>
using namespace std ;

class TypeA {
 public:
  int a[10] ;
  TypeA () {
    int i ;
    for ( i = 0; i != 9; i++) {
      a[i] = double(i) ;
    }
  }
  void printval() {
    int i ;
    for ( i = 0; i != 9; i++) {
      cout << a[i] << endl ; 
    }
  }
  ~TypeA() {
    //delete[] a;
    cout << "TypeA destructor called"<<endl;
  }

} ;


int main() {
  TypeA * ptrA = new TypeA() ;
  ptrA->printval();
  delete ptrA ;

  return 0 ;
}

通过new TypeA(),在堆上实例化一个对象,返回一个指针并保存在main()中。我想知道 a[]TypeA 是否存储在堆上?如果是这样,释放它的适当方法是什么?

解决方法

通常,除非您的类包含指针,否则整个对象都包含在一个分配中。因此,您无需执行任何特殊操作即可清除它。

您可以在您之前调用 delete[] 的事物上调用 new[],并且它必须完全与您之前的指针相同给。由于从未直接实例化 a 属性,因此对其调用 delete 是未定义的行为。

new 在概念上的工作方式并不是那么奇特,它只是分配 sizeof(X) 字节并调用该对象的构造函数。 new[] 的不同仅在于它分配 sizeof(X) * N 字节并调用构造函数 N 次。

,

试试这个代码:

#include <iostream>
#include <type_traits>
#include <cassert>
struct A{
    A() {
        std::cout<<"Called A() for "<<std::hex<<this<<'\n';
    }
};

struct B {
    A arr[10];
    B() {
        std::cout<<"Called B() for "<<std::hex<<this<<'\n';
    }
};

int main() {
    B* ptr = new B;
    static_assert(std::is_standard_layout<B>::value); //Sanity check for this example's case
    std::cout<<"Got ptr = "<<std::hex<<ptr<<std::dec<<" + sizeof(B)  = "<<sizeof(B)<<'\n';
    delete ptr;
    return 0;
}

输出为:

Called A() for 0x10d4eb0
Called A() for 0x10d4eb1
Called A() for 0x10d4eb2
Called A() for 0x10d4eb3
Called A() for 0x10d4eb4
Called A() for 0x10d4eb5
Called A() for 0x10d4eb6
Called A() for 0x10d4eb7
Called A() for 0x10d4eb8
Called A() for 0x10d4eb9
Called B() for 0x10d4eb0
Got ptr = 0x10d4eb0 + sizeof(B)  = 10

如果您看到代码和相应的输出,您可以将类型为 ptr 的对象 B 分配在 0x10d4eb0 处的堆上并且它的大小为 10 (对应 10 个字节,每个对象 A 1 个字节)。所以从 0x10d4eb00x10d4eb9 的内存地址都在堆上。而如果你看到A对象的地址,它们都在这个地址范围内。因此,A 的对象确实位于堆内存区域中。

现在谈到如何处理 arr,需要调用 delete/delete[],视情况而定,仅在使用 new 分配的对象上/new[]。由于 arr 不是这种情况,因此不需要对其调用 delete[]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。