静态变量存储在哪里?

4
根据参考资料,很多人说静态变量被存储在数据段中。这意味着如果我在两个以上的函数中声明了相同的静态变量名字,数据段中将包含多个相同变量的声明。如果是这样,是否会发生冲突?
那么,静态变量存放在哪里?我认为它们存储在文本段中。因此,在每次函数迭代时,静态变量中的值保持不变。如果它在数据段中,就会发生冲突。如果它在堆栈中,变量的作用域将延伸到函数的生命周期,因此无法维护变量中存储的值。这样对吗?

文本段存储程序代码。变量不能存储在文本段中,因为它们不是程序代码。(显而易见) - mangusta
3
全局静态变量还是局部静态变量?需要注意的是,这取决于实现(编译器),C规范并没有对此(或类似“段”之类的东西)做出任何说明。 - Some programmer dude
2
你的困惑源于你认为如果在两个不同的函数中使用相同的名称,那么名称会发生冲突。但事实并非如此,不存在这样的冲突。两个不同的变量会被创建。克服这种误解,你的问题就会消失。 - David Heffernan
编译器会为每个全局静态变量的名称添加前缀,从而使其具有唯一性。这个前缀通常来源于变量所声明的文件名(这就是为什么在头文件中声明这样的变量时可能会出现链接错误——如果头文件在多个源文件中被包含,则同一个全局变量将被声明多次)。 - barak manos
避免是否应该询问这些问题。对于大多数编译器,初始化的静态变量存储在.data段中。如果您在全局或函数范围内将变量未初始化(或初始化为0),它将被放置在.bss段中,并在运行时启动时设置为0。 - D M Lowe
4个回答

2

静态变量存储在内存的数据段中。它们的生命周期持续到程序终止。但是它们的作用域仅限于声明它们的函数。如果声明为全局变量,则作用域仅限于声明它们的文件。


如果变量存储在数据段中,那么这些变量就像全局变量一样可以从程序的任何地方访问。是不是这样呢?那么静态变量如何被放置在数据段中并且其作用域仅限于函数内部呢?这是否可能? - mohangraj
1
@mohan 你为什么关心segments?听起来你对这一切的工作原理的心理模型是错误的。你正在以错误的层次思考这个问题。至少现在先忘记segments吧。毕竟,标准没有提到它们。专注于理解语言而不是一个特定的实现。 - David Heffernan
@DavidHeffernan 不是这样的。我只是想知道静态变量与其他变量一样是如何在内部存储的。例如:如果我想要关于此话题进行一个会话,我必须了解静态变量的从头到尾。在那里,我无法给出这种类型的答案。我们并不是说没有标准实现的参考。我们寻找答案的方式可能是错误的。但是,答案总会有的。我们要一直找到找到为止。无论如何,感谢您的帮助... - mohangraj
你的方法不正确。知道它们存储在哪里并没有什么帮助。如果在不同于你的机器的机器上实现,那该怎么办呢?首先要高层次地理解语言。 - David Heffernan
1
@mohan:我的朋友,静态变量存储在数据段中,根据你的说法,它可以像全局变量一样从程序的任何地方访问。我理解你的观点,但是让我向你澄清一下,静态变量的作用域仅限于使用它的模块,但其生命周期贯穿整个程序的运行期间。 - Rishabh Dwivedi

0
在已初始化数据段中,通常也称为数据段。 数据段是程序虚拟地址空间的一部分,其中包含全局变量和由程序员初始化的静态变量。

0
变量的存储位置取决于变量的生命周期。 静态变量的寿命就是整个程序的寿命。 因此,静态变量和全局变量都存储在内存的数据段中。数据段

0

静态变量存储在代码的数据段中。实际上,内存被分为三个主要部分:

  • 文本、数据和堆栈/堆

文本段仅存储编译后的实际可执行文件。因此,静态变量不可能存储在文本段中。

堆栈和堆包含动态数据,即在堆栈中声明的作用域(局部变量)的变量,在堆中包括全局/外部/未分配类型(通过malloc、calloc等分配的内存),每个函数调用都会创建一个新的堆栈。
这是许多递归代码由于堆栈溢出而导致分段错误的原因之一

现在,具有静态链接的变量(静态变量、只读数据和未初始化数据)除了内存的数据段之外别无选择。现在可以有局部静态变量和全局静态变量。C总是更喜欢具有相同名称的局部变量而不是全局变量,因此在“c”中除非在同一作用域中声明具有相同名称的变量,否则不会发生名称冲突。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接