我有以下代码片段:
std::vector<std::string> v1;
v1.push_back("Hello");
v1.push_back("World");
std::vector<std::string> v2;
v2.push_back("Good");
v2.push_back("Bye");
v1 = v2;
Run Code Online (Sandbox Code Playgroud)
vector 的旧值会发生什么v1
。
或者
v1
破坏时,它们会破坏。那么我怎样才能立即释放它们呢?在调用之前保存在容器中的任何元素要么被分配给要么被销毁。
因此,在您的示例中,原始基础std::string
值将对它们进行std::string::operator=
调用,并且它们(基础std::string
本身)不会被破坏。
如果分配给的向量大于从分配的向量,那么您将调用析构函数以获取向量中的元素,例如:
std::vector<std::string> v1;
v1.push_back("Hello");
v1.push_back("There");
v1.push_back("World");
std::vector<std::string> v2;
v2.push_back("Good");
v2.push_back("Bye");
v1 = v2;
Run Code Online (Sandbox Code Playgroud)
在这个例子中,std::string
对于值"Hello"
和"There"
将被分配"Good"
并"Bye"
分别同时的第三串"World"
将被破坏。
但要记住这适用仅包含在所述载体中的元件,采取下面的代码,例如:
std::vector<int*> v1;
v1.push_back(new int(42));
v1.push_back(new int(24));
v1.push_back(new int(38));
std::vector<int*> v2;
v2.push_back(new int(32));
v2.push_back(new int(23));
v1 = v2;
Run Code Online (Sandbox Code Playgroud)
在这段代码中,发生内存泄漏是因为v1
一个包含指针的向量,指针本身被分配/销毁,而不是它指向的值。此示例等效于以下内容:
int* x = new int(42);
int* y = new int(24);
x = y; // memory leak here
Run Code Online (Sandbox Code Playgroud)
为此,如果您希望从向量中移除元素(从而调用容器中每个元素的析构函数),您可以使用clear
清除向量中所有元素的方法,或者您也可以使用该erase
方法,它可以擦除单个或多个元素。
相同的规则适用于clear
和erase
;如果底层类型是已声明内存的指针类型,则需要确保delete
向量中的元素;例子:
template < typename IteratorType >
void delete_elements(IteratorType start, IteratorType end)
{
while (start != end) {
delete (*start); // or delete[]
++start;
}
}
std::vector<int*> v1;
v1.push_back(new int(42));
v1.push_back(new int(24));
v1.push_back(new int(38));
delete_elements(v1.begin(), v1.end());
Run Code Online (Sandbox Code Playgroud)
如果你想看到这个作业的实际效果,你可以使用一个像下面代码一样的小测试类:
#include <iostream>
#include <string>
#include <vector>
#define outi(v) std::cout << v << ", i = " << i << std::endl
class tester {
public:
tester() : i(42) { outi("default ctor"); }
tester(int x) : i(x) { outi("implicit ctor"); }
~tester() { outi("dtor"); }
tester(const tester& cp) : i(cp.i) { outi("copy ctor"); }
tester& operator=(const tester& cp) {
this->i = cp.i;
outi("operator=");
return *this;
}
// for std::cout << tester;
friend std::ostream& operator<<(std::ostream& o, const tester& t) {
o << t.i; return o;
}
private:
int i;
};
template < typename itr >
static void printall(itr start, itr end)
{
while (start != end) {
std::cout << (*start) << std::endl;
++start;
}
}
int main(int argc, char* argv[])
{
std::vector<tester> v1;
std::cout << "create v1 elements" << std::endl;
v1.push_back(10); // implicit ctor calls
v1.push_back(24);
v1.push_back(33);
printall(v1.begin(), v1.end());
std::vector<tester> v2;
std::cout << "create v2 elements" << std::endl;
v2.push_back(tester(100));
v2.push_back(tester(99));
printall(v2.begin(), v2.end());
std::cout << "v1 = v2" << std::endl;
//v1.clear(); // uncomment to call dtor's
v1 = v2;
printall(v1.begin(), v1.end());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该程序的输出可能如下所示:
create v1 elements
implicit ctor, i = 10
copy ctor, i = 10
dtor, i = 10
implicit ctor, i = 24
copy ctor, i = 10
dtor, i = 10
copy ctor, i = 24
dtor, i = 24
implicit ctor, i = 33
copy ctor, i = 10
copy ctor, i = 24
dtor, i = 10
dtor, i = 24
copy ctor, i = 33
dtor, i = 33
10
24
33
create v2 elements
implicit ctor, i = 100
copy ctor, i = 100
dtor, i = 100
implicit ctor, i = 99
copy ctor, i = 100
dtor, i = 100
copy ctor, i = 99
dtor, i = 99
100
99
v1 = v2
operator=, i = 100
operator=, i = 99
dtor, i = 33
100
99
dtor, i = 100
dtor, i = 99
dtor, i = 100
dtor, i = 99
Run Code Online (Sandbox Code Playgroud)
我说可能是因为您的编译器可以选择对构造函数/赋值的排序略有不同,但结果将是相同的。
我希望能有所帮助。