C++ 变量内存分配

标签 c++ memory-management compiler-theory conditional-compilation new-operator

这些主要是编译器设计问题。当你的编译器编译它时,例如:

int * pData = new int[256];

内存是如何分配的?编译器是调用为您分配内存的操作系统例程,还是编译后的函数为您分配内存?

另外,当你这样写的时候:

if (x == 5)
    int y;

由于内存不是在运行时分配的,我假设数据在程序的数据段中占用了一些空间。由于编译器无法真正确定 int y; 分支是否会在运行时执行,是否为变量保留的内存是否 int y; 是执行?如果它无论如何都被保留,内存分配 block 中可能会或可能不会执行的任何变量不是更节省内存吗?

谢谢

最佳答案

对于第一个问题:当编译器遇到 new 运算符时,就像您的示例中一样:

int * pData = new int[256];

它有效地发出如下代码:

int *pData = reinterpret_cast<int*>(::operator new(256 * sizeof(int)));
// the compiler may also choose to reserve extra space here or elsewhere to
// "remember" how many elements were allocated by this new[] so delete[] 
// can properly call all the destructors too!

如果应该调用一个构造函数,它也会被发出(在这个例子中,我相信没有调用构造函数)。

operator new(std::size_t) 是一个由标准库实现的函数,通常但不总是,它会归结为一个malloc 调用。

malloc 必须生成一个 system call , 从操作系统请求内存。由于 OS 分配器通常使用较大的固定大小的内存块,因此 malloc 不会每次都进行此调用,只有在它耗尽当前拥有的内存时才进行。


对于第二个问题:对于局部变量,这真的取决于编译器。该标准没有提及堆栈。但是,很可能您使用的是运行通用操作系统并使用通用编译器的通用架构:-)。

因此对于常见情况,编译器通常会在函数调用开始时为所有局部变量保留空间,方法是相应地调整堆栈或为它们保留寄存器(如果可以的话)首选,因为它快得多)。

然后(在c++中),当遇到变量时,它会调用构造函数。从理论上讲,它可以根据需要调整堆栈,但这很难证明是正确的,而且效率较低。通常,保留堆栈空间是一条指令,因此一次完成所有操作是非常理想的。

关于C++ 变量内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5544145/

相关文章:

c++ - 在 QT-C++ 中制作 exe 文件缺少 qt5cored dll

c++ - 遍历链表 : while(ptr! =NULL) vs while(ptr->next!=NULL)?

language-agnostic - 为什么托管语言不提供手动删除对象的能力?

language-agnostic - 正式构建控制流图

c - 编译器如何知道堆栈或堆上是否分配了某些内容?

c++ - 绕行 GetComputerNameW

c++ - VC++ LNK2019 错误我似乎无法修复

java - 当没有可用内存时,Java如何创建OutOfMemoryError对象

c - 内存映射显示的 RAM 多于物理可用的 RAM

c++ - 解析 C++ 的复杂性