From this link,它说使用c ++向量时有四个步骤进行内存重新分配......
我对数字3和4特别感兴趣,是否可以通过代码执行这些任务?或者它只是在后台发生。
即,我能够"消灭记忆中的元素"通过C ++中的代码?我能直接"释放内存"用C ++代码?
答案 0 :(得分:2)
是的,是的!您可能希望查看operator new
类型,或新展示位置,operator delete
,析构函数调用和{{1}}。 (请注意,operator new和operator delete是分配和释放函数的名称,与new和delete运算符不同。)
希望这有帮助!
答案 1 :(得分:1)
我能通过C ++中的代码“破坏内存中的元素吗?”
是。通过调用对象的析构函数。例如,如果void test() {
Foo.foo((Value<Boolean> value) -> true).booleanValue();
}
是对x
类型对象的引用,则可以使用以下命令销毁该对象:
T
我能否在C ++代码中直接“释放内存”?
当然。存在各种解除分配功能,其具有相应的分配功能。如果您使用x.~T();
分配,则会使用malloc
取消分配。如果您使用free
分配,则会使用operator new()
取消分配。如果您使用operator delete()
分配,则会使用new char[]
解除分配。
答案 2 :(得分:1)
您可以使用简单的STL函数..
您可以使用vector::erase
成员函数从向量中移除单个元素或一系列元素,
iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
然后,在C ++ 11下,调用vector::shrink_to_fit
来请求容器将其容量减少到当前大小。 (请注意,实现可以自由地忽略此请求。)
void shrink_to_fit();
或使用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());
*如果你调整到比实际尺寸更小的尺寸 - 假设你的矢量有10个元素,你调整大小为size_t = 7,之后你的矢量将只有前7个元素,其余的将是破坏。
此外,如果您只想销毁某些特定元素,则可以使用Erase-remove idiom
- https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom,然后使用shrink_to_fit()
或resize()
。
答案 3 :(得分:0)
是的,在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();
分配和构造实例也是如此。有一些内存可以使用placement new来调用构造函数。
此外,构造函数和析构函数不仅仅是关于管理内存,它们还可以帮助打开文件,当前播放音乐或者几乎所有需要初始化和完成的内容。
我希望这个快速而粗略的旅程可以帮助您理解基本概念。我遗漏了很多东西,并且在某些方面并不准确,所以仅将其作为进一步研究的基础