2014-02-27 41 views
2

目前,我们正在努力跟踪存储在内存中的变量,但我们面临以下问题,也许你会帮助我们全局变量用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和A的sizeofÿ我得到4 那么什么是0x028EE84和0x028EE86之间(整数类型和字符的大小)1?为什么它需要7个位置才能将char变量插入到内存中而不是将其插入0x028EE81内存位置?

+3

这是一个64位的机器,对吧?它被称为对齐。有一个很好的答案在这里解释它:http://stackoverflow.com/questions/381244/purpose-of-memory-alignment – Fredrik

+0

“int”在位置80,81,82,83,位置84,85处的“char” ,86,87,在最右边。 –

+5

仔细查看打印输出。变量比你想象的要多得多。除非你有复制粘贴错误。 –

回答

0

因为编译器可以自由插入填充以获得更好效果alignment

如果您绝对必须在内存中将它们紧挨着放在一起,请将它们放在struct中并使用#pragma pack强制将填充对齐设置为1(无填充)。

#pragma pack(push, 1) 

struct MyStruct 
{ 
    int x; 
    char y; 
}; 

#pragma pack(pop) 

这在技术上是编译器相关的行为(而不是由C++标准执行),但我发现它是主要语言编译器之间相当一致。

1

一般来说,编译器会尝试做一些所谓的对齐。这意味着编译器将尝试使变量以2,4,8,16,...的倍数结束,具体取决于机器体系结构。通过这样做,内存访问和写入速度更快。

1

这里已经有很多非常好的答案,但我不觉得它们中的任何一个都达到了这个问题的核心。编译器决定将全局变量放入内存的位置不是由C或C++定义的。虽然程序员可能很方便地连续存储变量,但是编译器有关于您的特定系统的大量信息,因此可以提供各种各样的优化,可能会导致它以最初不明显的方式使用内存。

也许编译器决定把int放在一个内存区域中,并使用其他类型的相同的对齐方式,并将字符卡在一些不需要对齐的字符串中。

但是,其实质是编译器没有义务或承诺它将在内存中存储大多数类型的变量,并且缺少读取编译器的完整源代码的信息,因此没有简单的方法来理解它为什么会这样做所以。如果你关心这个如此糟糕,你不应该使用单独的变量,考虑把它们放入一个结构,然后有一个定义良好的内存放置规则(注意填充仍然是允许的)。