内存分配(C++)编译时间/运行时间?

问题描述:

我不知道如何适当的就是这个问题,但 -内存分配(C++)编译时间/运行时间?

我好奇的编译器是如何为它的构造,甚至之前(甚至构造函数被调用之前的对象(内存分配),可将内存一边去! )

它是如何发生的基本数据类型?

这听起来有点幼稚,但它究竟是什么?

它是完全运行时间过程,或者它(编译)有像任何计划要做到这一点,在运行时,它在编译期在手之前决定时间。我根本不知道!

对象,无论是原始类型,指针还是大类的实例都占用一定量的已知内存。这种记忆必须以某种方式留给对象。在某些情况下,该预留存储器被初始化。初始化是构造函数的作用。它们不会留出(或分配)存储对象所需的内存。该步骤在调用构造函数之前执行。

换句话说,什么时候从字面上ANY类型的变量的内存分配发生,在时间上,在哪一点?编译(或运行时)的哪个步骤?

内存分配总是在运行时发生。对于驻留在堆栈中的对象或静态变量,内存预留发生在编译时(或在C99 VLA的运行时)。

内存为对象的成员总是在地方构造运行之前。确保编译器及其运行时支持的工作就是如此。

+0

静态变量可能会在可执行文件本身中被赋予空间(然后被内存映射到进程的地址空间中),所以它们在编译时被完全分配。 :) – jalf

+0

谢谢大卫...... :)但是这导致了一个小问题。 **内存分配**和**内存预留**!从你所说的话,我明白两者之间是有区别的。你能解释给我吗? :) – jsp99

+0

@jalf我忘记了这一点。我已将静态变量添加到我称为保留的类别,而不是分配。 –

使用newnew[]或某些变体创建的分配对象在运行时完成,方法是在构造函数运行之前访问freestore并找到足够空间放置新对象。

函数内的本地对象的分配在运行时完成。然而,这通常通过将堆栈指针移动到正确的字节大小来实现,并且现在为对象保留之前值和新值之间的空间。构造函数在空间运行后运行。

对全局和静态对象

分配是在编译时由编译器完成,它们的构造函数,当他们在加载定义的转换单元(通常在main()开始执行)运行。另一个目的内

分配用于直接包含的对象(未通过指针)作为分配给该对象的一部分来完成。

+1

我会说,本地对象的大部分分配是在编译时完成的,因为编译器发出的机器代码期望对象相对于当前的堆栈帧处于特定偏移量,并且此偏移量在编译时决定时间。 –

有(严格意义上)三种典型的方案:在栈上分配,从堆分配和静态分配。

首先是当你在函数内声明的局部变量会发生什么:

void foo () 
{ 
    int bar = 42; 
} 

这里,bar内存是在stack分配。它被调用时分配foo

void foo () 
{ 
    MyClass* bar = new MyClass(); 
} 

这里,i内存是在heap分配:

第二种情况,当你创建一个new操作一个类的实例发生。这又发生在运行时,并且在new运算符执行时发生。如果你对此更熟悉,它的工作原理与C的malloc相同。

最后,有静态分配。

void foo () 
{ 
    static int bar = 42; 
} 

这里,编译器知道提前时间内存将需要bar,所以它插入到可执行告诉可执行文件加载器来预留空间的指令,或从字面上使得空间在可执行的因此bar的内存通常仍在运行时分配,因为可执行程序会加载。

+1

我怀疑静态分配“字面上”占用可执行映像中的空间。设想一个全局'char buf [1000000];'你的可执行文件不会增长1MB,而是在*加载时间内将内存留出。 –