如何为堆栈变量分配内存

How is memory allocated for stack variables?

本文关键字:分配 内存 变量 堆栈      更新时间:2023-10-16

在VS(发行版)上,我运行以下程序:

int main(void)
{
   char b[] = "123";
   char a[] = "1234567";
   printf("%x  %xn", b,a);
   return 0;
}

我可以看到,a的mem地址是b+3(字符串的长度)。这表明内存是在没有间隙的情况下分配的。这保证了使用最少的内存。所以,我现在有点相信所有的编译器都会这么做。我想在这里确认一下这个猜测。有人能给我一个更正式的证据吗?或者告诉我,我的猜测源于巧合。

不,不能保证总是有完美的数据打包。

例如,我在g++上编译并运行了这段代码,结果相差8。

你可以在这里阅读更多关于这方面的信息。

tl;dr:编译器可以将内存中的对象只对齐到可以被某个常数整除的地址(总是机器字长),以帮助处理器(对他们来说,使用这样的地址更容易)

UPD:关于对齐的一个有趣的例子:

#include <iostream>
using namespace std;
struct A
{
    int a;
    char b;
    int c;
    char d;
};
struct B
{
    int a;
    int c;
    char b;
    char d;
};
int main()
{
    cout << sizeof(A) << " " << sizeof(B) << "n";
}

对我来说,它打印

16 12

不能保证为每个变量选择什么地址。例如,不同的处理器可能对变量的对齐有不同的要求或偏好。

此外,我希望在您的示例中,地址之间至少有4个字节。"123"需要4个字节——额外的字节用于空终止符。

尝试颠倒声明a[]和b[]的顺序,和/或增加b的长度。

您对如何分配存储做了很大的假设。根据编译器的不同,字符串文字可能存储在不在堆栈上的文字池中。然而,a[]和b[]确实占用了堆栈上的元素。因此,另一个测试是添加int c并比较这些地址。