[英]C++: Static pointers, static objects and dynamic memory allocation
考虑下面的代码段:
#include <iostream>
using namespace std;
class p
{
public:
int* q;
p()
{
q = new int(100);
}
~p(){
delete q;
}
};
static p* p1 = new p();
static p p2;
int main() {
// your code goes here
std::cout << *(p1->q);
std::cout << *(p2.q);
delete p1;
}
p1和p2是静态变量,它们必须存储在静态段中。
由于p1是指针,因此仅将指针地址存储在静态段中还是指向它的对象中?
p2是一个普通的静态对象,但是它包含一个动态分配的成员变量q,q也存储在静态段中吗?
p1
是一个指针,它存储在静态段中(我不确定这是正确的术语), p1
指向的对象或内存在堆上。
p2
是一个对象,它存储在静态段中。 q
是p2
内的指针, q
指向的对象或内存在堆上。
您有两个静态分配的对象,一个名为p1
的指针和一个名为p2
的类型p
的实例。
程序中有两个地方可以进行动态分配:在类p
的构造函数中,以及在初始化静态变量p1
。
只要程序运行,静态分配的对象p1
(指针)和p2
(类实例)就存在。 将仅包含一个地址的指针p1
与该地址处的类实例区分开是很重要的。 (该实例将在运行时由new p()
)。 指针和“指针”可以具有独立的生存期; 两者彼此独立存在。 指针可能存在而不指向任何东西,并且由new p()
调用创建的对象的存在可能比指向它的任何指针的存在时间都长。 1
这是程序启动时发生的事件序列。 静态变量的初始化在C ++ 11标准的3.6.2节中指定。
具有静态存储持续时间的变量的分配,此处为p1
和p2
。 一个有效的模型是内存是程序的一部分。
这些变量归零。 “具有静态存储持续时间的变量应在进行任何其他初始化之前进行零初始化。” 指针p1
以及p2
所在的内存现在由全为零的字节组成。
按定义顺序对这些变量进行动态(即运行时)初始化 :
p1
初始化从调用new p()
。
p
的新对象的内存。 内存的内容未初始化且未知。 该对象没有名称,因此我们将其称为x
。 x
'构造函数以对其进行初始化。
xq
。 xq
是x
一部分,因此驻留在之前动态分配的内存中。 new
另一个调用,这次是int。 标准分配器为初始化为100的int动态分配内存。 new
的返回值是int所在的内存地址,该地址分配给int指针xq
。 x
'构造函数返回,而new p()
返回x
所在的内存地址。 p1
,该p1
现在指向我们称为x
的未命名p
实例。 p2
初始化。 p2
的构造函数被执行,其功能与上述x
的构造函数相同:它对int调用new
,该int会导致动态内存分配,将其初始化为100并将int内存位置的地址分配给p2.q
下图显示了有关内存位置和对象之间关系的结果。
这应该有助于回答您的问题:
p1
在“静态段”中,但是它指向的对象已在运行时通过对new
的调用而动态分配。 p2
不包含“动态分配的成员变量q”。 该语句使成员变量(名为q
的指针)与q
指向的对象(动态分配的int)混淆。 成员变量q
存储在存储类p
的包含实例的任何位置; 实际上,它是该实例中的唯一数据。 (尝试sizeof(p)
!)任何实例的成员q
指向的对象始终是动态分配的int(嗯,直到某个恶意的程序员为您的public q
分配了不同的值)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.