局部变量排序问题

时间:2018-03-19 20:55:56

标签: c local-variables

我注意到我用C编写的某些程序没有在我的机器上运行,但是它们与其他程序一样。所以为了测试这个,我编写了一个简单的程序来测试堆栈如何推送和弹出局部变量:

#include <stdio.h>
#include <string.h>

int main() {
    char char_test[10];
    int int_test = 0;

    strcpy(char_test, "Hello");
}

然后我调试了这个程序,发现int_test的内存地址比char_test高,即使根据我的知识,第一个声明的局部变量应该有更高的内存地址。然后我添加了两个打印函数,用于打印变量的内存地址:

#include <stdio.h>
#include <string.h>

int main() {
    char char_test[10];
    int int_test = 0;

    strcpy(char_test, "Hello");

    printf("Address of char_test: 0x%x\n", &char_test);
    printf("Address of int_test: 0x%x\n", &int_test);
}

现在,第一个局部变量的内存地址高于第二个。打印地址会改变变量的顺序吗?我做错了吗?

3 个答案:

答案 0 :(得分:2)

您所引用的顺序要求适用于struct的成员。编译器不需要以某种方式对局部变量进行排序。实际上,没有要求编译器将堆栈用于其自动变量,甚至根本不需要分配它们,如果它可以侥幸逃脱它。

在您的示例中,编译器看起来就是这样:由于未使用int_test,编译器假装它不存在。一旦你开始使用它的地址,编译器就被迫分配它。碰巧在char_test之前分配变量,但没有义务这样做。

答案 1 :(得分:2)

内存中变量的排序(无论它们是本地还是全局)都与任何合理的程序无关。

已经错误的程序的行为当然可以取决于变量的相对接近程度(特别是溢出的数组),但这显然是因为程序已经错了。

而且,不,没有规则可以管理,也不保证您的编译器(和链接器)将如何分配地址。

答案 2 :(得分:1)

内存中变量的排序是编译器的实现细节。

它可能将它们按顺序排列,或按相反顺序排列,或按数据类型或其他方式分组。这与一个编译器的不同之处不同,也可能因不同的优化级别而不同。此外,正如您所见,使用哪种策略可能会因看似无关的代码更改而发生变化。

C标准对如何完成此操作没有任何要求,因此您无法依赖其订单。