繁体   English   中英

全局变量在C中不连续

[英]Global Variables not contiguous in C

当前,我们正在尝试跟踪存储在内存中的变量,但是我们面临以下问题,也许您会帮助我们

当前,我们在代码中定义了一些全局变量,如下所示

int x;
char y;

并且我们添加了以下代码行

int main ( int argc, char *argv[ ] ){ 
printf("Memory of x %p\n",&x); 
printf("Memory of y %p\n",&y);
system( "pause");
return 0;
}

程序返回了以下地址

Memory of x 0x028EE80
Memory of y 0x028EE87

如果我使sizeof x和sizeof y得到4和1(整数和char类型的大小),那么0x028EE84和0x028EE86之间是什么? 为什么要花7个位置才能将char变量插入内存中,而不是将其插入0x028EE81内存位置?

通常,编译器将尝试执行称为对齐的操作。 这意味着编译器将尝试使变量以2、4、8、16 ...的倍数结尾,具体取决于机器的体系结构。 这样,内存访问和写入速度更快。

这里已经有很多非常好的答案,但是我认为其中没有一个是这个问题的核心。 编译器决定将全局变量放置在内存中的位置不是由C或C ++定义的。 尽管对于程序员来说,连续存储变量似乎很方便,但是编译器具有与您的特定系统有关的大量信息,因此可以提供广泛的优化选择,也许使编译器以最初并不明显的方式使用内存。

也许编译器决定将int与其他类型的相同对齐方式放在内存区域中,并将char粘在不需要对齐的某些字符串中。

尽管如此,其本质还是在于,编译器对将大多数类型的变量存储在内存中的位置不承担任何义务或承诺,而且如果不阅读编译器的全部源代码,就很难理解为什么这样做。 如果您非常在意此问题,则不应使用单独的变量,请考虑将其放入结构中,该结构具有明确定义的内存放置规则(仍然允许填充)。

因为编译器可以自由插入填充以获取更好的对齐方式

如果绝对必须在内存中将它们紧挨着,请将它们放在struct然后使用#pragma pack强制将包装对齐方式设置为1(无填充)。

#pragma pack(push, 1)

struct MyStruct
{
    int x;
    char y;
};

#pragma pack(pop)

从技术上讲,这是与编译器有关的行为(不是由C ++标准强制执行),但是我发现在主要的编译器中,它是相当一致的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM