为什么我的对象似乎在不使用new”的情况下在堆上
Why does my object appear to be on the heap without using `new`?
我开始学习动态内存分配的主题。
我有以下代码:
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main() {
/* Both objects on Stack */
A classAStack;
B classBStack;
/* Both objects on Heap*/
// A *classAHeap = new A();
// B *classBHeap = new B();
/* A objects on Heap B ???*/
A *classAHeap = new A();
return 0;
}
#ifndef A_H_
#define A_H_
#include <iostream>
#include "B.h"
class A {
public:
A();
virtual ~A();
public:
B b;
};
#endif /* A_H_ */
#include "A.h"
A::A() {
std::cout <<"Constructor A called" << std::endl;
}
A::~A() {
}
#ifndef B_H_
#define B_H_
#include <iostream>
class B {
public:
B();
virtual ~B();
};
#endif /* B_H_ */
#include "B.h"
B::B() {
std::cout <<"Constructor B called" << std::endl;
}
B::~B() {
}
调试器的输出是:
临时断点6,main((at ../src/heapstacktest02.cpp:1818 classastack;断点4,b :: b(this = 0x23aa58(at ../src/b.cpp:1212 std :: cout&lt;&lt;" constructor b chater"&lt;&lt;std :: endl;断点5,a :: a(this = 0x23aa50(at ../src/a.cpp:1313 std :: cout&lt;&lt;" constructor a nath&lt;&lt;std :: endl;断点4,b :: b(this = 0x23aa40(at ../src/b.cpp:1212 std :: cout&lt;&lt;" constructor b chater"&lt;&lt;std :: endl;断点4,b :: b(this = 0x60004b048(at ../src/b.cpp:1212 std :: cout&lt;&lt;" constructor b chater"&lt;&lt;std :: endl;断点5,a :: a(this = 0x60004b040(at ../src/a.cpp:1313 std :: cout&lt;&lt;" constructor a nath&lt;&lt;std :: endl;断点1,main((at ../src/heapstacktest02.cpp:3030返回0;
我的问题:
A
类的成员变量b
在哪里?
如果我查看第0x23a节中的地址,它似乎是堆栈,并且第0x6000节似乎是堆。
我正在使用Windows 64位系统。
为什么会员变量的b
也在堆上,而没有称为new
操作员?
成员是b
是您动态分配的对象的一部分,因此它是该动态分配的一部分,并且位于内存中的同一位置。
如果成员不是对象的一部分,剩下什么?您将有什么动态分配?
这就是为什么当您看到new
时避免术语"在堆上"的原因。"堆在堆上"不仅是您new
的事情。不,new
动态分配一个对象以及对象直接包含的所有内容。您编写对象的声明与它是"在堆上"或"堆栈上"是否注定要失败之间的任何精神关联。
确定对象存储持续时间的唯一可靠方法是了解其历史记录。确定对象存储位置的唯一可靠方法是不要打扰。
要回答这个问题,让我们开始找出我们拥有多少个B类实例。答案是3。
一个实例是A型的成员B(在堆栈上(。另一个是堆栈上B的实例,第三个是A型A类型B的成员B的实例。
为什么要堆?它在那里,因为您在堆上创建了类型A的实例,并且A的实例是B作为成员的实例。
所以B的3个实例之一在堆上,另外2个在堆上。
考虑以下内容:
#include <iostream>
#include <string>
class B {
public:
int64_t x = 42;
int64_t y = 7;
};
class A1 {
public:
B b;
};
class A2 {
public:
A2() { b = new B(); }
B* b;
~A2() { delete b; }
};
int main() {
std::cout << sizeof(A1) << std::endl; // prints 16
std::cout << sizeof(A2) << std::endl; // prints 8
// Section (2)
A1 a1; // Instance of A1 and B are on the stack
A2 a2; // Instance of A2 is on the stack. B is on the heap.
A1* a3 = new A1();
std::cout << a3 == &(a3->b) << std:: endl; // prints true
A2* a4 = new A2();
std::cout << a4 == a4->b << std::endl; // prints false
return 0;
}
相关文章:
- 如何在不使用new的情况下保持在其他对象中创建的对象存活?
- 如何在不使用 "new" 关键字的情况下解除分配创建的对象的内存?
- (C++)如何在不导致 mem 泄漏的情况下将指针传递到分配了'new'的函数?
- C++:为什么可以在没有事先使用 new 的情况下在指向结构的指针上使用 delete?
- 为什么我的对象似乎在不使用new”的情况下在堆上
- 为什么在这种情况下使用 int *arr = new int [number]
- 如何在不使用 new 的情况下进行默认初始化
- 如果在没有 new 运算符的情况下初始化,C++是否将类对象视为值类型
- 在使用new和delete的情况下交叉编译错误
- 尝试在没有new的情况下使用我的自定义类构造函数
- 在不使用"new"的情况下实例化参数参数中的对象
- 在不先显式调用析构函数的情况下,在旧对象上使用placement new是否危险
- 'new'语句是否可以在不引发异常的情况下失败?
- 在没有“new”关键字的情况下实例化类会导致在堆栈或堆上创建其内部变量
- 如何在不复制的情况下取消引用使用 New 创建的指针
- 在没有 new 关键字的情况下初始化C++对象的内存从何而来
- 重写类运算符new并在不更改类的情况下删除
- 在没有提供参数的情况下,如何调用我的重载new
- 如何在不使用默认构造函数的情况下通过new创建对象的动态大小数组
- 在C++中,如何在没有动态分配(即NEW)的情况下将对象初始化为对象内部的指针