0

我正在使用 ubuntu 12.04 和 Qt Creator 2.4.1。它默认构建我的 C 代码GCC

我正在调试我的程序 ( Qt Creator (uses GDB)),并且已经可以看到许多将在程序的后续步骤中调用/创建的变量。在程序开始时看到所有变量是否正常?换句话说,我是否因为调试选项(-g)而在程序的早期看到了变量?例如,我“进入”代码并在第一步停止int main() 一只忙碌的猫

char[1000] mesg;在第 129 行执行,但是我已经可以看到它和它的内存地址。或int tem_hopt_dist=0;在第 230 行,但我已经看到它的值为“3”。

4

2 回答 2

4

具有“静态持续时间”的变量(与static关键字不同,尽管static通常声明的变量确实具有静态持续时间)在执行模型中,由main调用时间“创建”。具有“自动持续时间”的变量(“在堆栈上”,正如许多人所说的那样)是在进入其范围时创建的。malloc通过last until 显式分配的变量freed (或通过 减少空间realloc等)。

上面的关键要点不是“此时创建”,而是“此时创建”。如果效率更高,编译器可以更早地自由执行此操作。对于块范围的自动持续时间变量,将它们全部集中到一个大的入口点堆栈分配中通常是最便宜的,编译器可以在最典型的情况下使用单个“减法”指令(“从堆栈指针中减去常量”)来完成现代机器。释放空间要么完全免费(“从函数返回”),要么再次只需要一条指令(“将常量添加到堆栈指针”)。

C99 的可变长度数组(“VLA”)使这有点复杂。一个 VLA 通常必须在每次进入其封闭块时分配,并在每次退出块时释放。同样,这通常相当便宜(从堆栈指针中减去一个以创建 VLA,一个添加以销毁它),但显然每块两条指令比每块零指令更昂贵。这也会稍微干扰一些编译时优化。

如果您曾经使用过非标准alloca函数,这通常也是通过从堆栈指针中减法来实现的,并且它可能无法与 VLA“很好地配合”,因为这种减法倾向于假定编译器已经完成了自己的“减法”从堆栈指针”恰好一次,就在函数本身开始之前。

于 2012-06-16T18:10:33.220 回答
2

是的,这很正常。调试器不理解语言的所有范围语义,并显示数据,就好像所有变量都在其最终内存位置初始化一样,即使它们超出范围。

一些调试器比其他的更好。这是一个常见的刺激源,例如,如果您习惯将单独的索引变量全部调用i,并且调试器不会区分它们。

于 2012-06-16T17:54:15.350 回答