内存中的变量是以C++存储的变量吗?

问题描述:

如果我有这样的代码:内存中的变量是以C++存储的变量吗?

int e; 
int* f; 

int main() { 
    int a, b, c; 
    int* d; 
} 

在内存中存储这些变量? 而且,定义全局变量有什么问题(在这种情况下,像函数中的函数一样)?

+4

阅读此:http://www.gotw.ca/gotw/009.htm – 2010-06-26 17:12:57

+0

非常感谢您的链接! – Puyover 2010-06-26 17:33:09

a,b,c和d将存在于堆栈中。如果你要创建一个int实例(使用malloc或new),那么这个实例就会在堆上 - 但是名为'd'的指针仍然会存在于堆栈中。

E和F在应用程序的内存空间分配的空间,在所谓的“数据段” - 看到:

http://en.wikipedia.org/wiki/Data_segment

你还问到堆栈大小:那年代由编译器配置,在这里看到:

http://msdn.microsoft.com/en-us/library/tdkhxaks(VS.71).aspx

+0

噢,谢谢。非常有用的关于数据段的信息!关于堆栈大小谢谢,我现在更清楚:) – Puyover 2010-06-26 17:21:25

+0

使用任何优化编译器,位于堆栈上的本地机器是一种可能的事情。从概念上说,他们都在筹备中,但大多数情况下这不会反映现实。 – 2010-06-27 02:40:38

+0

同意,为了做得更多,他们将被转移到注册表(http://en.wikipedia.org/wiki/Processor_register)。但问'在哪里分配局部变量'的答案是'堆栈':) – 2010-06-27 08:35:35

你为什么认为这很重要?请注意,在现代C++中,拥有局部指针变量非常罕见。

在典型的系统上,a,b,c和d将存在于堆栈中。但是这是一个实现细节,语言标准没有具体说明这一点。

+0

有什么办法,我可以知道标准PC中堆栈的大小是多少? – Puyover 2010-06-26 17:12:02

+0

堆栈大小是线程特定的。 – 2010-06-26 17:13:00

+0

...并找出给定线程的堆栈大小是特定于操作系统的。在Windows中,您可以通过检索线程信息块(32位)或线程环境块(64位)来获取此信息。 – stinky472 2010-06-27 01:23:12

实际上并没有关于变量在内存中放置的保证,只有行为。

但在大多数(或许是全部)实际系统中,ef将在全球数据部分,而abcd在寄存器中的混合和调用堆栈上。 fd都可以指向内存中的任何位置(好吧,对于MMU来说,这并非完全正确,它们可以指向映射到进程中的内存子集中的任何位置)。

+0

谢谢。那么我可以根据需要定义许多全局变量,而不会产生性能问题/空间? – Puyover 2010-06-26 17:14:52

+4

@Puy:你肯定会遇到许多全局变量的设计问题。 – fredoverflow 2010-06-26 17:20:40

+0

你可以有很多全局变量,但是所有静态分配的变量都必须被初始化,这会减慢程序的启动速度。它可能不足以注意到。正如Fred所说,尽管使用大量全局变量会使程序难以维护,所以不建议这样做。更好的做法是不需要外部链接的文件范围变量,这可以使用C++中的无名称命名空间或C中的static关键字(不推荐用于C++)完成,并且不会像全局变量那样容易地导致意大利面条代码。 – 2010-06-27 02:38:56

重点是变量的范围,它定义了它们的生命周期。主程序的变量外观将在您的程序期间可用。 main()函数的持续时间内main中的变量将可用。

实际上,函数范围变量通常在堆栈上分配,而全局变量在堆上分配,但这是一个实现细节。

全局变量的主要问题是控制访问,他们可能很难在多线程程序中使用。

编辑:正如@FredOverflow指出下面,全局通常分配在加载可执行映像时设置的数据区域。

+0

我很确定全局变量不是从堆中分配的,而是从数据段中分配的。 – fredoverflow 2010-06-26 17:17:37

+0

@Fred - 你是对的。我的思维跟不上我的打字! – mdma 2010-06-26 17:56:50

通常,a,b,c,d *将在程序堆栈中定义,尽管C++ ISO标准没有指定应定义变量的位置。

对于第二个问题,全局变量的问题是他们没有保护。对于依赖于全局变量的简单脚本/应用程序来说可能没有问题,但是在库和更复杂的代码中,它会产生一个潜在的问题:任何代码都可以随时更改全局变量的值,留下任何依赖全局变量的代码一个不希望的状态。

此外,由于变量位于全局范围内,因此如果您使用任何其他定义具有相同名称的全局变量的代码,那么它们将面临潜在的命名冲突。