c - C 代码的混淆行为与阴影结构声明
问题描述
考虑以下 C 代码:
#include <stdio.h>
typedef struct {
int a;
} TestType;
int main(){
int an_int;
TestType test;
// printf("%d\n",test.a);
{
TestType test;
test.a = 777;
printf("offset: %lld\n", &test.a - &an_int); // maybe 2?
}
printf("%d\n", test.a); // should be garbage
printf("offset: %lld\n", &test.a - &an_int); // maybe 1?
}
我声明 a TestType test
,然后启动一个范围并TestType test
首先声明另一个阴影。最后打印语句的预期输出是堆栈上的任何内容。编译gcc -o stack-allocate-weird stack-allocate-weird.c
并运行,我得到输出:
offset: 1
777
offset: 1
所以这两个位置是一样的。此外,valgrind ./stack-allocate-weird
报告没有错误。取消注释第一个打印语句给了我预期的输出:
-771776240
offset: 2
-771776240
offset: 1
如果不是struct TestType
我只声明一个int
,则代码的行为符合预期(最后一个打印语句打印垃圾)。
我将代码放到服务器上并编译它并得到:
offset: -2
0
offset: -1
哪个看起来也不错(我猜堆栈的方向相反?)。另一方面,将在我的计算机上编译的二进制文件移到服务器上会产生原始的错误输出:
offset: 1
777
offset: 1
这是 gcc 的已知错误吗?
gcc -v
在我的电脑上说(一堆其他的东西和):
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04)
在服务器上它说:
gcc version 8.3.1 20190223 (Red Hat 8.3.1-2) (GCC)
所以也许这在两者之间得到了解决?
解决方案
我认为这不是 GCC 的错误。编译器会延迟外部的分配,TestType test
直到需要它为止。这是在第printf()
16 行的第二个。内部TestType test
被放置在偏移量 1 处,就像你看到的那样,直到它的范围关闭并且它的内存再次空闲。现在需要外部的并占用相同的空间,为您提供内部的值和相同的偏移量。
推荐阅读
- android - 在 WebView Android 上使用 Whatsapp HREF
- azure-cosmosdb - Cosmos 相当于 map/select
- reactjs - 将查询参数添加到 React Router 中的当前 URL?
- javafx - 具有 CSS 滚动问题的 JavaFX tableview
- amazon-web-services - 处理程序中的 Alexa Skill Lambda Node.js 动态意图
- android - Android MVP - Presenter 显示值(最佳实践)
- laravel - 如何在创建资源时用 auth 用户填充用户 ID 字段?
- google-sheets - 添加迄今为止的月份,分数
- jboss - Wildfly 14 域 - 连接超时
- opengl - 为平面实现各向异性照明