C ++向量实现 - 删除元素

时间:2012-03-14 15:36:34

标签: c++ algorithm data-structures vector

我正在实现一种矢量类型。我对算法或数据结构完全没有困扰,但我不确定是否有一种删除方法。例如:

bool Remove(Node* node)
{
 /* rearrange all the links and extract the node */

 delete node;
}

其中node是指向我们当前节点的指针。但是,如果我删除节点,那么我该如何防止这种情况发生:

Node* currentNode = MoveToRandNode();
Remove(currentNode);
cout << currentNode->value;

如果currentNode是指向指针的指针,那么它会更容易但是......它不是。

5 个答案:

答案 0 :(得分:2)

您可以为迭代器添加另一个抽象级别(现在是一个原始指针) 如果你不处理原始指针,但是创建某种迭代器类而不是指针,则可能使迭代器无效,因此如果有人在删除迭代器后尝试访问迭代器,则会失败控制。

 class Iterator {
     Node operator*() {
       if (node) return *node; 
       else throw Something();}
   private:
     Node* node;
 }

当然,指针的包装将花费一些开销(检查每个deref上的指针)。所以你必须决定你想玩多么安全。可以是其他人建议的文件,也可以是安全包装。

答案 1 :(得分:1)

先退一步。您需要定义谁“拥有”向量指向的内存。是矢量本身,还是使用矢量的代码?一旦你定义了这个,答案就很简单 - Remove()方法应该总是删除它或从不删除它。

请注意,您只是触及了可能的错误表面,而您回答“谁拥有它”将有助于解决其他可能的问题:

  • 如果复制矢量,是否需要复制其中的项目,或仅复制指针(例如,执行浅或深复制
  • 当你摧毁一个向量时,你应该销毁它中的项目吗?
  • 当您插入项目时,是否应该复制该项目,或者该向量是否拥有该项目的所有权?

答案 2 :(得分:0)

嗯,你不能这样做,但对你的代码进行一些修改可以提高安全性。 添加参考

bool Remove(Node*& node)
{
 /* rearrange all the links and extract the node */

 delete node;
 node = nullptr;
}

检查nullptr

if(currentNode)
    cout << currentNode->value;

可能你需要尝试std :: shared_ptr

答案 3 :(得分:0)

这类似于“迭代器失效”。例如,如果您有std::list lstd::list::iterator it指向该列表,并且您调用l.erase(it),那么迭代器it将失效 - 即,如果您使用它无论如何,你会得到未定义的行为。

因此,根据该示例,您应该在您的文档中包含Remove方法:“指针node无效,并且在此方法返回后可能无法使用或取消引用。”

(当然,你也可以使用std :: list,而不用费心去重新发明轮子。)

有关迭代器失效的详细信息,请参阅:http://www.angelikalanger.com/Conferences/Slides/CppInvalidIterators-DevConnections-2002.pdf

答案 4 :(得分:0)

另外,innochenti写道。 我认为你必须决定cout << currentNode->value;

的预期/期望行为
  • 错误 - (正如innochenti写的node = nullptr
  • 默认值 - 创建节点devault_value(其value有一些默认值),delete node;node=default_value