- 为所需的新容量分配足够的内存;
- 将元素从旧内存复制到新内存;
- 销毁旧内存中的元素;
- 并释放旧内存。
也就是说,我能否通过C++代码“销毁内存中的元素”?我能否直接在C++代码中“释放内存”?
std::allocator
类型或者了解放置 new,operator new
,析构函数调用和 operator delete
。请注意,operator new
和 operator delete
是分配和释放内存的函数名称,不同于 new 和 delete 运算符。
希望这能帮到你!
x
是类型为T
的对象的引用,您可以使用以下代码销毁该对象:x.~T();
malloc
进行内存分配,则需要使用free
来释放;如果你使用了operator new()
进行内存分配,则需要使用operator delete()
来释放;如果你使用了new char[]
进行内存分配,则需要使用delete[]
来释放。std::vector
上执行这些操作?如果是后者,那么你不应该这样做,因为std::vector
会自动完成所有这些操作。 - Benjamin Lindleyvector
,它应该调用数组版本的删除对。 - ixScistd::vector
通过其分配器处理其分配和释放。std::vector
的默认分配器是 std::allocator
。std::allocator::deallocate
调用的是 operator delete(void*)
,而不是 operator delete[](void*)
。 - Benjamin Lindleyyou could use the vector::erase
member function to remove a single element or a range of elements from your vector,
iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
and then, under C++11, call vector::shrink_to_fit
to request the container to reduce it's capacity to exactly it's current size. (Note that the implementation is free to ignore this request though..)
void shrink_to_fit();
or use vector::resize
void resize (size_type n);
void resize (size_type n, const value_type& val);
对于类似这样的内容:
myVector.erase(myVector.begin(), myVector.begin() + 3);
myVector.shrink_to_fit();
myVector.erase(myVector.begin(), myVector.begin() + 3);
resize(myVector.size());
shrink_to_fit()
或 resize()
。是的,在C++中,销毁和释放数据既可能也是必须的。
通常情况下,数据可以存在于C++中的两个位置:
.
void fn(void) {
Data data;
}
void fn2(void) {
Data * dataptr;
dataptr = new Data();
delete dataptr;
}
在这个函数中,与上面相同的事情正在发生,只是使用了一个指针,你可以将其视为描述内存某个位置的整数。(仅在理论上如此,因为像这样的指针没有构造函数或析构函数)
但是接下来还有第二和第三行:在堆中分配和构造了一个Data实例,并在之后进行了析构和释放。但我不必在那里立即执行它。我可以存储指针并在函数返回后长时间使用它来访问实例。
所有这些都包装在类中,例如vector,以提供与托管语言中相同的便利性,只有在需要时才能使用它,而不是被迫使用它。
作为示例,这里是一个玩具向量,仅显示资源管理部分:
struct vec {
size_t size;
int * values;
vec() {
// constructor, may do anything here
size = 0;
values = nullptr;
}
free() {
if (values != nullptr) {
delete [] values;
}
}
void push_back(int v) {
// allocating new memory
int * newvalues = new int[size + 1];
// copy existing values
for (size_t it = 0; it < size; ++it) {
newvalues[it] = values[it];
}
// delete original values
free ();
// add new value at the now free spot
newvalues[size] = v;
++size;
// update the pointer to point to the new memory
values = newvalues;
}
~vec() {
// destructor, may do anything here
free();
}
};
再说一遍:这只是玩具代码,用来说明一般思路,对于真正的代码还有很多要考虑的。
最后注意:在释放内存和销毁对象时,通常是同时进行的。这几乎是你所需要的。但你也可以手动调用析构函数:
Data data;
// ...
data.~Data();
对于分配和构造实例也是如此。有一些内存可以使用放置 new 来调用构造函数。
此外,构造函数和析构函数不仅仅是关于管理内存,它们还可以帮助打开文件、播放音乐或几乎所有需要初始化和完成的事情。
我希望这个快速而粗略的介绍能够帮助您理解基本概念。我省略了很多内容,并且在某些地方不够精确,因此只能将其用作进一步研究的基础。