【发布时间】:2011-03-17 06:33:06
【问题描述】:
我是 C++ 的新手,遇到了一个问题。
我在一本书中读到,一旦创建了该类的对象,就会将内存分配给静态变量。现在,如果我将这个静态变量设为全局怎么办?这种情况下什么时候初始化?
另外,我还在一些文章中读到静态变量分配在堆上并且它们不依赖于对象的构造......这是真的吗?如果是,请给我解释一下内存初始化步骤,我需要帮助。
非常感谢!
【问题讨论】:
标签: c++ memory static initialization
我是 C++ 的新手,遇到了一个问题。
我在一本书中读到,一旦创建了该类的对象,就会将内存分配给静态变量。现在,如果我将这个静态变量设为全局怎么办?这种情况下什么时候初始化?
另外,我还在一些文章中读到静态变量分配在堆上并且它们不依赖于对象的构造......这是真的吗?如果是,请给我解释一下内存初始化步骤,我需要帮助。
非常感谢!
【问题讨论】:
标签: c++ memory static initialization
首先:停止思考 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)的变量都在程序启动之前分配和初始化。如果您不指定初始值,它们将在 UNSPECIFIED ORDER 中默认初始化。 (对于原始类型,这只是意味着用零填充)。
静态变量仅在程序退出时被释放。这意味着,函数 f 中的“x”将仅初始化一次(在程序启动时),并且它将在函数调用之间保留其值(与将在每个函数条目上分配并在每个函数处释放的 y 不同)退出,因此它的价值也被破坏了)。请注意,在函数中使用静态变量与多线程和重入非常不兼容,除非您非常清楚自己在做什么。
【讨论】:
静态变量根本不存储在堆中。
未初始化的静态变量存储在 BSS 段中。
初始化的静态变量存储在数据段中。
您可以阅读这篇文章,它以很好的方式解释了所有这些: http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory
【讨论】:
在程序启动时(在主程序之前)将为您的静态全局变量分配内存。
我不知道第二个问题。
【讨论】: