我正在实现一种矢量类型。我对算法或数据结构完全没有困扰,但我不确定是否有一种删除方法。例如:
bool Remove(Node* node)
{
/* rearrange all the links and extract the node */
delete node;
}
其中node是指向我们当前节点的指针。但是,如果我删除节点,那么我该如何防止这种情况发生:
Node* currentNode = MoveToRandNode();
Remove(currentNode);
cout << currentNode->value;
如果currentNode是指向指针的指针,那么它会更容易但是......它不是。
答案 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 l
和std::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;
:
node = nullptr
)value
有一些默认值),delete node;
后node=default_value