我有这个代码,我想知道内存分配。
void f(){
static A a;
//Other things...
}
class A {
public:
A();
private:
AnotherObjectType anotherObject;
};
anotherObject
将在哪里分配?在static
代码段或其他地方?是否存在覆盖anotherObject
的风险? (f
将被多次调用)。
答案 0 :(得分:5)
所有非堆对象都将位于静态段中,位于f()的静态A实例中。
关于覆盖,如果你在多线程代码中使用了各种单例惯用语,这可能发生在旧的C / C ++中。但是例如较新的gcc版本使用新标准要求进行静态对象的自动线程安全初始化。参见例如Is local static variable initialization thread-safe in C++11?
答案 1 :(得分:1)
内存分配静态或动态。动态分配是在运行时分配内存时获得的,例如new
和malloc
。静态分配是“其余的”。类成员变量的内存与类实例一起分配,因此如果静态分配,则成员最终位于内存的同一部分,如果动态分配,则成员最终会占用动态内存所在的位置。对于指针成员变量也是如此,但它指向的实际内存可以是动态(new
和malloc
)或静态分配。
int i = 0;
int* pi = &i; // pi points at statically allocated memory
pi = new int(0); // pi points at dynamically allocated memory
因此,如果你有一个静态类实例,那么它及其成员的内存通常是在代码段中分配,但这是一个实现细节。
如果成员是一个指向动态分配内存的指针,那么该内存将所使用的分配器决定。 “堆”是动态分配内存的最常见实现细节,使用new
和malloc
时通常获取,但可以使用自定义分配器,即使在代码段中也能控制其他地方的内存。
答案 2 :(得分:0)
变量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://www.learncpp.com/cpp-tutorial/811-static-member-variables/
答案 3 :(得分:0)
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;
};
因此,另一个对象不会被覆盖,因为static A a
在静态段中创建一个A实例,而其他任何实例将在其他段中被创建,具体取决于您将创建它的段。
答案 4 :(得分:0)
尽管两者都称为 static ,但静态成员与静态局部变量不同。
在类中共享静态成员。该类的每个实例都指向同一个成员。
静态局部变量初始化一次,并且在函数返回时不会被销毁。
在您的代码中,非静态成员存储在实例a
中,a
在函数返回之后仍然存在。