这些大多是编译器设计问题。例如,当您的编译器编译此代码时:
int * pData = new int[256];
内存是如何动态分配的?编译器是调用为您分配内存的OS例程,还是编译为您分配内存的函数?
另外,当你写下这样的代码时:
if (x == 5)
int y;因为内存不是在运行时分配的,所以我假设数据在程序的数据段中占据了一些空间。由于编译器不能真正确定是否在运行时执行int y;分支,那么是否为执行int y;的变量保留内存?如果它是保留的,那么分配块中可能执行或可能不执行的任何变量不是更有内存效率吗?
o.o谢谢
发布于 2011-04-05 04:56:02
第一个问题的:当编译器遇到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++中),当遇到变量时,它将调用构造函数。从理论上讲,它可以根据需要调整堆栈,但这将是复杂的,以证明正确和较低的效率。通常情况下,保留堆栈空间是一条指令,因此一次完成所有操作是非常理想的。
发布于 2011-04-05 04:51:04
如何动态分配内存?编译器是调用为您分配内存的OS例程,还是编译为您分配内存的函数?
在大多数实现中,它是这两者的结合。通常有一个操作系统服务用于为您的进程提供内存块,也有一些运行时或标准库中的代码在您的应用程序中以更细粒度的规模管理这些内存块。
是否为变量保留的内存,无论是否执行"int y;“?如果它是保留的,那么分配块中可能执行或可能不执行的任何变量不是更有内存效率吗?
通常情况下,no -只有在执行适当的代码时才会分配y的空间。具有自动存储类的变量通常在堆栈上,因此为它们腾出空间就像修改堆栈指针一样容易。也就是说,编译器在这种情况下可以做任何它想做的事情,所以检查工具链的输出是唯一确定的方法。
发布于 2011-04-05 04:51:04
局部变量(int,y)在堆栈上分配。
同样的事情也适用于指针,但是‘new’ed表达式是在堆上分配的,通常是通过一种malloc调用。确切的方法和堆布局是由实现定义的。
只有全局静态数据在数据段中。
示例int y将被优化,因为它没有被使用。
与C#不同,C++不允许缩小变量的作用域,因此在{ SomeClass y;}中包装短暂的局部可能会有所帮助,因此它会更早地被析构
但是,我非常确定,对于简单类型(如int),不存在这样的限制,因为对于这些类型永远不会有析构函数
https://stackoverflow.com/questions/5544145
复制相似问题