我一直在使用gprof在一个简单版本的向量上运行测试,该向量在堆上分配内存(实际上不是动态的 - 仅用于测试目的)。问题是,看到结果,我看到'new []'和'delete []'之间存在巨大差异 - 假设我实际上将值插入向量(使用[]运算符)。 做到这一点,我得到了如下结果:
% cumulative self self total
time seconds seconds calls s/call s/call name
0.92 0.55 0.01 1 5.03 5.03 MyVector::~MyVector()
0.00 0.55 0.00 1 0.00 0.00 MyVector::MyVector(int)
但是,如果我只是分配内存并删除它,而不是实际向向量插入值,它们 工作同样快:
% cumulative self self total
time seconds seconds calls ms/call ms/call name
0.00 0.09 0.00 1 0.00 0.00 MyVector::MyVector(int)
0.00 0.09 0.00 1 0.00 0.00 MyVector::~MyVector()
我的猜测是,当使用'new []'时,编译器(在我的情况下为gcc)并不真正分配内存,只有在需要时才会这样做(就像使用[]时)。当它需要破坏对象时,它就有了 取消分配在每次访问期间分配的所有内存(使用[])。
我找不到任何相关的文档 - 也许有些东西我不知道。我会幸福的 如果有人会分享他关于这个问题的知识。
编辑:我添加了我使用的代码。 感谢到目前为止的所有答案:
class MyVector
{
public:
MyVector(int size) { _data = new int[size]; };
~MyVector() { delete[] _data; } ;
int& operator[](int index) { return _data[i]; };
private:
int* _data;
int _size;
};
And the test:
int main() {
MyVector v(1000000);
for (int j = 0 ; j<20000 ; ++j) {
for (int i = 0; i<1000000; ++i) {
v[i]= i; //If i remove this line, destructor and constructor work just as fast
}
}
return 0;
}
答案 0 :(得分:1)
你是对的。 new[]
并不真正在所有系统上立即分配内存。例如,在Linux上,你得到一个指向内存的指针,只有在你尝试实际使用它时才会被分配。所以:
something = new[N];
delete[] something;
其中something
是指向内置类型的指针,几乎是无操作。
(这可能会违反标准一致性,因为new
应该在没有更多内存可用时抛出(或者在nothrow版本中返回NULL)。但这就是它的样子; Linux几乎将此视为它有无限的记忆。)
请注意,这仅适用于内置类型,因为它们不会使用new[]
进行默认构造,除非您要求它。其他类型的默认ctor被调用,因此访问内存。为了测试,请尝试访问最后一个元素:
something = new[N];
something[N-1] = some_Value;
delete[] something;
这会改变您的gprof结果吗?如果是,那么延迟分配很可能是你所看到的原因。