【问题标题】:copying elements from vector to another one将元素从向量复制到另一个
【发布时间】:2012-06-07 03:37:08
【问题描述】:

我有两个指针向量:arr 已经包含一些元素,temp,我想将特定元素从 arr 复制到的新向量。例如,我想复制arr 的第二个元素以复制到temp 并从arr 中删除。怎么办?

我试过了,但效果不好:

void deleteobject(vector < figure3d *> &arr,int index,vector < figure3d *> &temp)
{
     vector < figure3d * > :: iterator i=arr.begin();
     temp.insert(temp.begin(),*i);
     delete *i;
     arr.erase(i);
     temp[0]->print();
}

【问题讨论】:

  • 有什么不好的?
  • 如果你经常在向量的开头插入,那么你应该考虑把它改成双端队列。
  • Doug T - 怎么说不好?

标签: c++ stl vector


【解决方案1】:

您不应该 delete 复制的对象,因为您想将它保存在 temp 中 - 只需 erase 它来自 arr

【讨论】:

  • 它可以工作,Thankssssssss,但我没有记忆而不使用它吗?会不会有问题?
【解决方案2】:

arr.begin() 给你一个指向第一个元素的迭代器,所以如果你想要第二个元素,你应该提前i 一个:

++i;

如果你想要indexth 元素,你应该提前i index

i += index;

将原始指针存储在向量中,并且在从向量中删除它们时必须记住删除它们是等待发生的内存泄漏。而 ass molbdnilo 在另一个答案中提到,你实际上有一个内存处理错误,因为你正在删除 temp 指向的对象。

【讨论】:

    【解决方案3】:

    据我了解,您想复制指定索引处的元素(参数index)并将其从向量temp 中删除。这个函数看起来很简单:

    void deleteobject(std::vector<figure3d*> &arr, int index, std::vector<figure3d*> &temp)
    {
        temp.insert(temp.begin(), arr[index]);
        arr.erase(arr.begin() + index);
    }
    

    在这种情况下,您不会复制对象本身,而只是对其的引用——因此您不需要释放存储该对象的内存。

    另请注意,在您的函数中调用delete *i; 会释放存储i 指向的对象的内存 - 并且存储在arr 中的指针变得无效(悬空指针 ),因为它指向已经释放的内存。

    而且我还建议您使用对象向量而不是指向对象的指针向量 - 尽管元素会被复制,但它通常足够快,并且没有与之相关的麻烦内存管理。如果有充分的理由使用指针向量 (When to use pointers in C++), 我建议您改用智能指针向量:如果您支持 TR1 或 C++11,请使用 std::shared_ptr,否则使用 boost::shared_ptrWhere is shared_ptr?

    【讨论】:

    • 它可以工作,Thankssssssss,但我没有记忆而不使用它吗?会不会有问题?
    • @AsafShay:在这种情况下,您不会复制对象本身,而只是复制对它的引用——因此您不需要释放存储该对象的内存。
    • 我明白了。感谢大家的帮助。我处理了几个小时。再次坦克所有
    【解决方案4】:

    这看起来像是一份工作!
    我会这样做:

    Class removePredicate{
    Public: 
        bool operator() (figure3d** item) {
           //remove logic goes here
        }
    };
    
    remove_copy_if(arr.begin(), arr.end(), back_inserter(tmp), not1(removePredicate));
    

    这会将您要删除的所有元素复制到 tmp 中。要真正从 arr 中删除它们只是 remove-erase 习惯用法的简单应用:

    erase(remove_if(arr.begin(), arr.end(), not1(removePredicate)), arr.end());
    

    可能有一种方法可以将这两个步骤组合成一行,但您可能会失去可读性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多