c++ - 当我执行 std::vector = std::vector 时,std::vector 的旧值会发生什么

标签 c++ c++11 vector

我有以下代码片段:

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;

vector v1 的旧值会发生什么。

  • 旧值会被立即销毁吗?

  • 它们会在 vector v1 销毁时销毁。那我怎样才能立即释放它们呢?

最佳答案

根据to the references

Any elements held in the container before the call are either assigned to or destroyed.

因此,在您的示例中,原始底层 std::string 值将调用 std::string::operator= 并且它们(底层std::string 本身)不会被销毁。

如果被分配给的 vector 大于被分配给来自的 vector ,那么你会为 vector 中的元素调用析构函数,例如:

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;

在此示例中,"Hello""There"std::string 值将分配给 "Good ""Bye" 分别而 "World" 的第三个字符串将被销毁。

请记住,虽然这适用于 vector 中包含的元素,但以下面的代码为例:

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;

在这段代码中,由于 v1 是一个包含指针的 vector ,指针本身被分配/销毁,而不是它指向的值,因此发生了内存泄漏。此示例等效于以下内容:

int* x = new int(42);
int* y = new int(24);
x = y; // memory leak here

为此,如果您希望从 vector 中移除元素(从而调用容器中每个元素的析构函数),您可以使用 clear方法,它会清除 vector 中的所有元素,或者您也可以使用 erase方法,可以删除单个或多个元素。

同样的规则适用于clearerase;如果底层类型是已占用内存的指针类型,则需要确保delete vector 中的元素;示例:

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());

如果你想看到这个作业的实际效果,你可以使用像下面代码这样的小测试类:

#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;
}

此程序的输出可能如下所示:

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

我说可能是因为您的编译器可以选择对构造函数/赋值进行稍微不同的排序,但结果是相同的。

希望对您有所帮助。

关于c++ - 当我执行 std::vector = std::vector 时,std::vector 的旧值会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34804866/

相关文章:

c++ - 删除后内存泄漏 []

c++ - std::timed_mutex::try_lock_for 立即失败

c++ - 如何调用 clang++ 或 g++ 来准确复制两个不同标准版本中的需求

c++ - 我可以使用 std::align 将内存对齐到任意值 2 吗?

c++ - 对象 move 后,指向const vector 成员变量元素的指针是否保持稳定?

c++ - QI 在查询 IAMStreamConfig 时返回 E_NOINTERFACE

c++ - 显示来自 MFC DLL 的对话框

javascript - Phaser和Web Audio API-定向 Sprite

r - 查找向量或列中第二(第三...)最高/最低值的最快方法

c++ - 从接口(interface)序列化派生类