0

诸如 javascript 之类的高级语言不会让程序员选择变量的存储位置。但是C会。我的问题是:对于存储变量的位置是否有任何指导,例如取决于大小、使用情况等。

据我了解,存储数据的可能位置有三个(不包括用于实际代码的代码段):

  1. 数据段

那么临时的小数据项应该存储在堆栈上吗?

必须在函数之间共享的数据项呢?这些项目可以存储在堆上或数据段中。你如何决定选择哪个?

4

3 回答 3

2

当这些变量很小、经常使用并且在相对较小/有限的范围内使用时,您应该更喜欢局部/堆栈变量而不是全局或堆变量。这将使编译器有更多机会使用它们来优化代码,因为它知道它们不会在函数调用之间发生变化,除非你传递指向它们的指针。

此外,堆栈通常相对较小,在其上分配大型结构或数组可能会导致堆栈溢出,尤其是在递归代码中。

要考虑的另一件事是在多线程程序中使用全局变量。您希望最大限度地减少竞争条件的机会,一种策略是通过不直接使用其中的任何全局资源来使函数成为线程安全和可重入的(如果malloc()是线程安全的,如果errno是每线程等,您可以使用它们, 当然)。

顺便说一句,使用局部变量而不是全局变量也提高了代码的可读性,因为变量位于靠近它们使用的地方,您可以快速找出它们的类型以及它们的使用位置和方式。

除此之外,如果您的代码是正确的,那么在本地或全局或堆中创建变量之间应该没有太大的实际区别(当然,malloc()可能会失败,您应该记住它:)。

于 2013-04-05T14:48:19.577 回答
2

你从望远镜的错误一端看。您没有指定存储变量的特定内存段(特别是因为“内存段”的概念高度依赖于平台)。

在 C 代码中,您根据对代码有意义的内容来决定变量的生命周期可见性可修改性,并基于此编译器将生成机器代码以将对象存储在适当的段中(如果适用)

例如,在文件范围(任何函数之外)或使用关键字声明的任何变量static都将具有静态存储持续时间,这意味着它们在程序启动时分配并保持到程序终止;这些对象可以分配在数据段或 bss 段中。static在没有关键字的函数或块中声明的变量具有自动存储持续时间,并且(通常)在堆栈上分配。

字符串文字和其他编译时常量对象通常(但不总是!)分配在只读段中。像数字文字3.14159和像字符常量这样'A'的字符不是对象,并且(通常)没有为它们分配内存;相反,这些值直接嵌入机器代码指令中。

堆是为动态存储保留的,变量本身不存储在那里;相反,您使用库调用,例如malloc在运行时获取堆的一块,并将生成的指针值分配给如上所述分配的变量。该变量将存在于堆栈或数据段中,而它指向的内存则存在于堆中。

理想情况下,函数应该仅通过参数、返回值和异常(如果适用)进行通信;函数不应通过外部变量(即全局变量)共享数据。函数参数通常在堆栈上分配,尽管某些平台可能通过寄存器传递参数。

于 2013-04-05T15:14:59.907 回答
0

C 仅允许您通过变量和/或分配的范围来指定数据的间接存储位置。即,函数的局部变量通常是堆栈变量,除非它被声明为静态,在这种情况下它可能是 DATA/BSS。通过 new/malloc 动态创建的变量通常是堆的。

但是,不能保证任何...只有它的含义。

也就是说,保证是一个坏主意的一件事是在函数中声明大型局部变量......奇怪错误和堆栈溢出的常见来源。非常大的数组和结构最适合动态分配,并根据需要将指针保持在本地/全局中。

于 2013-04-05T14:50:31.067 回答