我是一个C++的新手,现在遇到了一个问题。
我在一本书中看到,当创建了一个类的对象后,静态变量就被分配了内存。那么,如果我将这个静态变量声明为全局的,它会在什么时候被初始化呢?
此外,我也在一些文章中读到过,静态变量被分配在堆上,它们不依赖于对象的构造...这是真的吗?如果是,请向我解释内存初始化的步骤,我需要帮助。
非常感谢!
我是一个C++的新手,现在遇到了一个问题。
我在一本书中看到,当创建了一个类的对象后,静态变量就被分配了内存。那么,如果我将这个静态变量声明为全局的,它会在什么时候被初始化呢?
此外,我也在一些文章中读到过,静态变量被分配在堆上,它们不依赖于对象的构造...这是真的吗?如果是,请向我解释内存初始化的步骤,我需要帮助。
非常感谢!
首先,请停止在C和C++中考虑全局变量,否则你将会持续处于困惑状态。该问题比如Python或Pascal等语言更加复杂,因此你不能仅使用一个单词来表示概念。
其次,“堆”和“栈”不存在 —— 它们属于操作系统和CPU的细节,与抽象的C++语言规范无关。
现在,变量有1)作用域,2)链接性和3)存储类别。使用static关键字可以影响这三个方面,具体取决于你在何处使用它。
作用域:变量声明的位置。如果在函数内部,则为函数作用域;如果在函数外部,则为文件作用域(你可能称之为“全局变量”)。
链接性:变量是否可以从其他编译单元中访问(当程序由多个源文件组成时相关)。
存储类别:
静态变量在程序启动时以实现定义的方式分配,并在程序结束前存在。它们不能被“释放”或“重新分配”。(像其他人提到的BSS和DATA段一样,这是典型的实现方法)。
自动变量仅存在于函数作用域中,它们在函数进入时分配(可能初始化)(通常在CPU的栈上),并在函数退出时销毁。
动态存储类别是你可能称之为“堆”的东西。这些变量的存储直接通过malloc/free或new/delete进行操作。静态变量的存储方式与动态存储完全不同,并且这两种存储方式基本上是不兼容的。
例如:
===
// ALL file-scope variables have static storage class
int global1; // file-scope, external linkage
static int global2; // file-scope, internal linkage
void f()
{
static int x; // static storage class, function-scope
int y; // automatic storage class, function-scope
free(&x); // ILLEGAL, WILL CRASH!
free(&y); // DITTO!
free(&global1); // DITTO!
}
===
现在,所有具有静态存储类(global1、global2和x)的变量都在程序启动之前分配并初始化。如果您没有指定初始值,则它们会以未指定的顺序进行默认初始化。(对于基本类型,这仅意味着填充零)。静态变量不会存储在堆中。
未初始化的静态变量存储在BSS段中。
已初始化的静态变量存储在Data Segment中。
您可以阅读这篇文章,其中对此进行了很好的解释:http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory
在程序启动时(main函数之前),将为您的静态全局变量分配内存。
我对第二个问题毫无头绪。