问题
Consider the below code segment:
#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 and p2 are static vars, they have to stored in static segment.
since p1 is a pointer, is only the pointer address stored in static segment or even the object it points to?
p2 is a normal static object, but it contains a dynamically allocated member variable q,so is q also stored in static segment?
回答1:
p1
is a pointer, it's stored in static segment (I am not sure it's the right term), the object or memoryp1
points to is on heap.p2
is an object, it's stored in static segment.q
is a pointer insidep2
, the object or memoryq
points to is on heap.
回答2:
You have two objects which are statically allocated, a pointer named p1
and an instance of type p
named p2
.
There are two places in your program where dynamic allocations can occur: in class p
's constructor and when the static variable p1
is initialized.
The statically allocated objects p1
(the pointer) and p2
(the class instance) exist as long as the program runs. It is important to distinguish the pointer p1
containing just an address from the class instance at that address. (That instance will be created at run time by new p()
). The pointer and the "pointee" can have independent lifetimes; both exist independently from each other. The pointer may exist and not point to anything, and the object created by the new p()
call may exist longer than any pointer to it.1
Here is the sequence of events which unfolds when your program starts. Initialization of static variables is specified in section 3.6.2 of the C++11 standard.
Allocation of variables with static storage duration, here
p1
andp2
. A working model of that is that the memory is part of the program.Zeroing of those variables. "Variables with static storage duration [...] shall be zero-initialized before any other initialization takes place." The pointer
p1
as well as the memory wherep2
resides now consist of bytes which are all zero.Dynamic (i.e. run-time) initialization of those variables in the order of their definition:
- Initialization of the pointer
p1
starts with callingnew p()
.- Memory for a new object of type
p
is allocated dynamically ("on the heap") with the standard allocator. The memory's contents is not initialized and unknown. The object doesn't have a name, so let's call itx
. x
' constructor is executed in order to initialize it.- The constructor assigns a value to the hitherto uninitialized member variable
x.q
.x.q
is part ofx
and as such resides in the memory dynamically allocated before. - The right hand side of the assignment is another call to
new
, this time for an int. The standard allocator dynamically allocates memory for an int which is initialized with 100. - The return value of
new
is the memory address where the int resides, which is assigned to the int pointerx.q
.
- The constructor assigns a value to the hitherto uninitialized member variable
x
' constructor returns, andnew p()
returns the memory address wherex
resides.- This return value is assigned to hitherto zero-initialized
p1
which now points to the unnamedp
instance we calledx
.
- Memory for a new object of type
- Initialization of
p2
.p2
's constructor is executed which does the same thing asx
's constructor above: It callsnew
for an int which causes a dynamic memory allocation, initializes it with 100 and assigns the address of the int's memory location top2.q
.
- Initialization of the pointer
The result, as far as memory locations and the relations between objects are concerned, is shown in the diagram below.
This should help answer your questions:
p1
is in the "static segment", if you want, but the object it points to has been dynamically allocated at run time by the call tonew
.- The static object
p2
does not contain "a dynamically allocated member variable q". That sentence confuses the member variable -- a pointer namedq
-- with the object to whichq
points, which is a dynamically allocated int. The member variableq
is stored wherever the containing instance of classp
is stored; in fact, it is the only data in that instance. (Trysizeof(p)
!) The object to which any instance's memberq
points is always a dynamically allocated int (well, that is until some malevolent programmer assigns a different value to your publicq
).
1That would constitute a memory leak because a dynamically allocated object whose address has been lost can never be deleted by the program.
来源:https://stackoverflow.com/questions/33492546/c-static-pointers-static-objects-and-dynamic-memory-allocation