【问题标题】:Memory allocation in stack堆栈中的内存分配
【发布时间】:2021-04-08 01:06:29
【问题描述】:

我有以下代码:

#include <iostream>
using namespace std;
int main()
{   
    int i, j;
    int *p = &i;    
            
    cout << "Address of i = " << &i << endl;
    cout << "Address of j = " << &j << ", which is " << &i - 1 << endl;
    cout << "Address of p = " << &p << ", which is NOT " << &j - 1 << endl;
}

我得到了以下输出(VS Code,带有 GCC):

Address of i = 0x61fe1c
Address of j = 0x61fe18, which is 0x61fe18
Address of p = 0x61fe10, which is NOT 0x61fe14

我认为局部变量,如 int 或指针,是在堆栈中连续分配的。所以我期待

Address of i = 0x61fe1c
Address of j = 0x61fe18
Address of p = 0x61fe14

我在这里错过了什么?

编辑:我想我明白了。指针指向变量的低地址。

#include <iostream>
using namespace std;
int main()
{   
    int i, j;
    int *p;
    int k, x;
            
    cout << "Address of i = " << &i << endl;
    cout << "Address of j = " << &j << ", which is " << &p + 1 << endl;
    cout << "Address of p = " << &p << ", which is " << &k + 1 << endl;
    cout << "Address of k = " << &k << ", which is " << &x + 1 << endl;     
}   

这给了我

Address of i = 0x61fe1c
Address of j = 0x61fe18, which is 0x61fe18
Address of p = 0x61fe10, which is 0x61fe10
Address of k = 0x61fe0c, which is 0x61fe0c

正如预期的那样。

【问题讨论】:

  • 存储变量的实际内存地址是否对您很重要?
  • 这里有一个提示:在您的机器上,sizeof(int) == 4sizeof(int*) == 8
  • 我认为局部变量,如 int 或指针,是在堆栈中连续分配的 -- 你从哪里得到这个(错误的)信息?
  • 我认为执行&amp;i - 1&amp;j - 1未定义的行为。对于手头的讨论和这个小程序可能并不重要。但不应该进入生产代码。
  • 栈本身是连续的。但是编译器可以没有义务将你声明的变量以特定的顺序放入堆栈。

标签: c++


【解决方案1】:

您并没有真正错过任何东西,但您的期望没有什么根据。

大多数编译器通常会使用所谓的“自然对齐”,这意味着项目的大小也是其所需的对齐方式。例如,如果您分配一个 4 字节的项目,它将被分配到一个 4 的倍数的地址。同样,一个 8 字节的项目,它的地址将是 8 的倍数。

在某些情况下,对齐甚至比这更严格,因此(例如)一个 16 字节的项目可能需要与一个 32 的倍数的地址对齐。这对于“向量”类型尤其常见,它持有单个大块中的多个操作数,并同时对多个操作数进行操作(例如,Intel AVX 或 PowerPC Altivec)。

例如,如果我有类似的东西:

int main() { 
    char x;
    int y;
}

我的通常期望是在 xy 之间看到 3 或 7 个未使用的字节(如果 sizeof(int) == 4 则为 3 个字节的填充,如果 sizeof(整数)== 8)。这不是严格要求的,但很常见,以至于如果它没有发生,那就有点令人惊讶了。

但不管确切的推理如何,编译器都可以在局部变量之间插入它认为合适的填充。在某些情况下(尤其是调试),他们可以/将插入额外的空间并用已知值填充它。然后在退出例程期间,他们会检查这些值是否保持不变,以合理保证您的代码没有写入不应写入的内存。

【讨论】:

    猜你喜欢
    • 2018-07-24
    • 2011-10-09
    • 2011-05-28
    • 2012-12-05
    • 2014-10-26
    • 1970-01-01
    • 2019-05-17
    • 2021-11-18
    相关资源
    最近更新 更多