全局变量在C中不连续

时间:2014-02-27 17:22:31

标签: c++ c pointers memory-management

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

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

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

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

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

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

然而,这个的本质是编译器没有义务或承诺它将大多数类型的变量存储在内存中,而没有读取编译器的完整源代码,没有简单的方法来理解为什么它这样做。如果您非常关心这一点,那么您不应该使用单独的变量,请考虑将它们放入一个结构中,然后该结构具有明确定义的内存放置规则(仍然允许填充填充)。

答案 2 :(得分:0)

因为编译器可以自由插入填充以便更好地alignment

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

#pragma pack(push, 1)

struct MyStruct
{
    int x;
    char y;
};

#pragma pack(pop)

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