在std :: move()

时间:2016-05-27 13:44:41

标签: c++ c++11 vector struct memory-leaks

我目前正在重构并将现有代码更改为C ++ 11,我想知道是否有内存泄漏。我的代码中包含一个std::vector的结构体,以及一个shrink()此向量到其负面元素的方法。

struct mystruct_t {

    int other_stuff;

    std::vector <int> loc;

    // Adds elements to loc vector
    void add(int pos){
        loc.push_back(pos);
    }

    // Shrink the list 
    void shrink () {
        std::vector<int> tmp;
        for (unsigned int i = 0; i < loc.size(); ++i) {
            if (loc[i] < 0) tmp.push_back (loc[i]);
        }
        loc = tmp;
        std::vector<int>(loc).swap (loc);
    }

    mystruct_t(): otherstuff(0) {};
};

在另一个函数中,我创建了这个结构的新实例,如下所示:

mystruct_t c = new mystruct_t;
c->add(2);
c->add(3);
...

后来我调用了这个结构的shrink()方法。

c->shrink()

现在我不确定&#34; old&#34;发生了什么?缩小函数后的loc矢量? 它会被自动销毁还是我必须手工销毁?如果是后者,我该怎么做?

我还尝试将shrink()更改为更多C ++ 11样式,方法是将其更改为:

void shrink (){        
    std::vector<int> tmp;
    for (auto &currLoc : loc) {
        if (currLoc < 0) tmp.push_back (currLoc);
    }
    loc = std::move(tmp);
}

但问题仍然与“老年人”发生的情况相同。此外,这似乎增加了内存使用量。我是C ++ 11的新手,不确定我是否完全误解了这个概念?

3 个答案:

答案 0 :(得分:2)

  

现在我不确定&#34; old&#34;发生了什么?收缩函数后的loc向量?

没有&#34; old&#34; loc向量。在mystruct_t对象的生命周期中,它只有一个成员向量loc。你永远不会得到一个新成员或扔掉旧成员。

当您将分配复制到成员(loc = tmp;)时,将更新缓冲区 - 在向量中。向量拥有缓冲区,向量注意它被正确销毁。在c ++ 11版本中移动assign时也是如此。

  

会自动销毁吗

如果你参考向量分配的内存,那么是。

  

还是我必须用手摧毁?

你必须手工摧毁你手工制作的任何东西。您没有拨打new,因此请勿拨打delete

  

此外,这似乎增加了内存使用量。

您的c ++ 11版本缺少&#34;缩小以适应&#34;原文的一部分(std::vector<int>(loc).swap (loc);)。在c ++ 11中,你可以这样做:

loc = std::move(tmp);
loc.shrink_to_fit();

在pre c ++ 11版本中,可以摆脱副本分配,只需从tmp构建临时,并将其与loc交换:

std::vector<int> tmp;
// copy the objects you want
std::vector<int>(tmp).swap(loc);

答案 1 :(得分:1)

操作std::move只是转换值,因此没有额外的内存使用量。

答案 2 :(得分:1)

当您使用std::move时,编译器将删除第一个对象的head address,并将内存重新分配给第二个对象。因此,只需更改head数据即可实现非常快速的操作等。