C++:如何在循环中的堆栈上创建对象
C++ : How does creating an object on stack within a loop works under the hood?
假设我有这样的代码:-
struct myStruct{
int a;
int b;
};
int main(){
for(int i=0; i<5; i++){
myStruct obj;
cout<<"Address of object in memory : "<<&obj<<endl;
}
return 0;
}
这实际上会在堆栈上创建 5 个不同的对象吗?如果是这样,为什么考虑到 obj 是实际对象而不是对对象的引用,它每次都打印完全相同的内存地址?我已经在网站上阅读了一些答案,但我仍然无法完全理解它。
如果你打印了相同的地址,那只是意味着内存空间被重用,并不意味着它们是相同的对象。
如果添加用户定义的构造函数(和析构函数(,您将看到构造(和析构(5个不同的对象:
struct myStruct{
myStruct() { std::cout << "ctorn"; }
~myStruct() { std::cout << "dtorn"; }
int a;
int b;
};
潜在结果:
ctor
Address of object in memory : 0x7fffc5be8c50
dtor
ctor
Address of object in memory : 0x7fffc5be8c50
dtor
ctor
Address of object in memory : 0x7fffc5be8c50
dtor
ctor
Address of object in memory : 0x7fffc5be8c50
dtor
ctor
Address of object in memory : 0x7fffc5be8c50
dtor
住
obj
在每次迭代开始时创建,并在结束时销毁。
如果将输出语句放在其构造函数和析构函数中,您将能够看到这种情况的发生。 (尽管从技术上讲,如果检测对象存在的唯一方法是跟踪构造函数和析构函数调用,则编译器可以自由地删除对象,但在这种情况下,大多数编译器可能不会,因为替代方法是在每次迭代开始时重新初始化对象(。
您还可以通过添加额外的范围来查看这一点。
int main()
{
for(int i=0; i<5; i++)
{
{ // extra scope here
myStruct obj;
cout<<"Address of object in memory : "<<&obj<<endl;
}
obj = something(); // will not compile since obj does not exist here
}
return 0;
}
对于使用堆栈(标准不需要的实现细节(的编译器,在一次迭代结束和下一次迭代开始之间,很有可能不会将其他变量放置在堆栈上。 这可以解释您看到所有具有相同地址的对象。
这实际上会在堆栈上创建 5 个不同的对象吗?
是的,它确实创建了 5 个不同的对象。它是否在堆栈上创建它是另一回事。它所说的只是,在循环的每次迭代中for
将静态创建一个新对象。现在,当一个对象是静态创建的时,它有一个预定义的范围和生存期,这是在编译时决定的。对于实例myStruct obj;
作用域for
循环。在每次迭代中是否为实例获取相同或不同的地址是实现定义的。
此外,每个对象都有自己的身份,可以通过它们是新创建的事实来验证(如其他答案中所述(。此外,此标识由对象的作用域、生存期、名称的组合定义。现在,此标识不能是对象的地址。
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何创建对象函数指针C++映射?
- C++创建对象数组
- 在 C++ 的 Switch Case 中创建对象后对对象调用方法
- 如何获取在 main() 函数中构造的类的创建对象?
- 基于文件中的条目创建对象
- 错误:创建对象后无法分配区域
- 堆还是堆栈用于创建对象?
- 在堆和堆栈中创建对象的差异
- 在堆栈上创建对象的不同方法
- C++:如何在循环中的堆栈上创建对象
- 在堆栈中创建对象时,即使代码覆盖率为100%,函数覆盖率也较小
- 如何使用在另一个类的构造函数中的堆栈上接受参数的构造函数创建对象
- 在堆栈上创建对象
- 在堆栈上创建对象时分配的内存在哪里
- 在堆栈/堆上创建对象
- 何时在堆与堆栈中创建对象
- 将引用分配给新创建的堆栈分配对象时会发生什么
- 在堆栈/堆上创建对象
- 在堆栈上创建对象矢量?(c++)