静态对象的非静态成员分配在哪里

Where are non-static member of a static object allocated?

本文关键字:分配 在哪里 静态成员 对象 静态      更新时间:2023-10-16

我有这段代码,我想知道内存分配的问题。

void f(){
static A a;
//Other things...
}
class A {
public:
A();
private:
AnotherObjectType anotherObject;
};

anotherObject将分配到哪里?在static代码段或其他地方?anotherObject是否存在被覆盖的风险?(f将被调用多次)。

所有非堆对象都将位于静态段中,位于f()的静态A实例内。

关于覆盖,如果在多线程代码中使用各种单例习惯用法,在旧的C/C++中可能会发生这种情况。但是,例如,较新的gcc版本使用了静态对象的自动线程安全初始化的新标准要求。例如,请参阅C++11中的本地静态变量初始化线程是否安全?

内存要么静态要么动态分配。动态分配是在运行时分配内存时得到的,例如newmalloc。静态分配是"其余部分"。类成员变量的内存是与类实例一起分配的,因此如果是静态分配的,则成员最终位于内存的同一部分,如果是动态分配的,那么成员最终位于动态内存所在的位置。指针成员变量也是如此,但它所指向的实际内存可以是动态的(newmalloc),也可以是静态分配的。

int i = 0;
int* pi = &i;     // pi points at statically allocated memory
pi = new int(0);  // pi points at dynamically allocated memory

因此,如果您有一个静态类实例,它及其成员的内存通常是在代码段中分配的,但这是一个实现细节。

如果该成员是一个指针,它指向动态分配的内存,则该内存将是所用分配器决定的。"堆"是动态分配内存最常见的实现细节,在使用newmalloc时通常会得到它,但可以使用自定义分配器来控制其他地方的内存,甚至是代码段中的内存。

变量a是一个静态变量,只声明一次,这意味着A a;语句只执行一次。变量的作用域在函数f作用域之上。字段anotherObject在A对象。

参见计数示例:

#include <iostream>
using namespace std;
class AnotherObjectType {};
class A {
public:
A(){count = 0;};
int count;
private:
AnotherObjectType anotherObject;
};
A f(){
static A a;
a.count++;
//Other things...
return a;
}
int main() {
// your code goes here
A a;
for (int i = 0; i < 3; i++) {
a = f();
std::cout << "Count: " << a.count  << std::endl;
}
return 0;
}

工作示例:http://ideone.com/USqeEZ

另请参阅:http://www.learncpp.com/cpp-tutorial/811-static-member-variables/

void f(){
/// this created in static segment - that's obviously for you
static A a;
//Other things...
}
class A {
public:
A();
private:
/// anotherObject is not pointer but explicit part of A,
/// so it won't be created in heap or anywhere else,
/// but in the same memory segment as an instance of A.
AnotherObjectType anotherObject;
};

因此,另一个Object不会被覆盖,因为static A a在静态段中创建了一个A实例,而任何其他实例都将被夹在其他段中,这取决于您将创建它的段。

虽然两者都被称为static,但静态成员不同于静态局部变量。

静态成员在类中共享。这个类的每个实例都引用同一个成员。

静态局部变量初始化一次,当函数返回时不会被销毁。

在您的代码中,非静态成员存储在实例a中,并且a在函数返回之后仍然存在。