首页 > 解决方案 > 使用正确的地址和数据为 C 创建一个堆栈图

问题描述

我正在尝试绘制一个堆栈,其中进程的底部是 0xffff。程序很简单:

int main() {
     char c;
     int i;
     double d;
     int iArr[4];
     return 0;
}

当我为地址的示例创建一个程序时,我得到了:

iArr[0]: 0x7ffce0c79970

iArr [1]: 0x7ffce0c79974

iArr[2]: 0x7ffce0c79978

iArr[3]: 0x7ffce0c7997c

d: 0x7ffce0c79980

我:0x7ffce0c79988

c: 0x7ffce0c7998f

sizeof() 函数说整数是 4 个字节,那为什么我从 88 变为 88e?另外,如果假定进程的底部是 0xffff,那么 c 会从 0xffff 还是 0xfffe 开始?

标签: cmemory-addresscallstack

解决方案


您将需要考虑对齐( alignof) 和大小( sizeof),因为某些类型必须在特定内存地址上对齐,否则 CPU 无法处理。

例如,int必须在一个 4 字节double的倍数、8 的倍数等地址上,而char只有一个字节可以去任何地方。

如果您将堆栈可视化,您会看到它是这样的:

         |    |    |    |    |    |    |    |    |
         +----+----+----+----+----+----+----+----+
 ...9970 |      iArr[0]      |       iArr[1]     |
         +----+----+----+----+----+----+----+----+
 ...9978 |      iArr[2]      |       iArr[3]     |
         +----+----+----+----+----+----+----+----+
 ...9980 |                   d                   |
         +----+----+----+----+----+----+----+----+
 ...9988 |         i         |    |    |    | c  |
         +----+----+----+----+----+----+----+----+

这是有道理的,因为堆栈趋于向下增长,即较早的条目具有更高的内存地址。所以c获取最高地址,然后i获取下一个可能的最高地址,考虑对齐,等等。数组以iArr尽可能高的对齐方式分配为连续的内存块,但索引的工作顺序与堆栈相反,它们总是向上计数,因此看起来很奇怪但也很有意义。


推荐阅读