【发布时间】:2020-10-10 21:01:11
【问题描述】:
我在为学校作业编写一些代码时遇到了一个小问题(我知道这在此处被回避,但我将自己锁定在使用 std::list 库并为此付费)。我有一个函数,它有一个指向传递给它的类的指针列表以及属于我想要销毁和调整列表大小的那些类之一的特定 ID。但是,使用我的代码,列表永远不会调整大小并且值是垃圾,这会使我的程序崩溃。所以看起来实际的类正在被删除,但该元素从未从列表中删除......
如果我有时间制作自己的双向链表实现,我会遍历列表以查找要删除的元素。如果找到,则创建一个临时节点指针并将其指向我将要删除的节点。将前一个节点的“next”元素设置为迭代器的“next”元素,然后删除迭代器节点。
但是.. 使用stl::list 实现,我不知所措。这是我到目前为止所拥有的,其中 DOCO 是一个类,列表中的元素是指向类实例的指针。我研究了remove() 与erase(),可能同时使用两者都可以解决问题,但我不确定如何使用这样的迭代器实现remove()。
bool DOCO::kill_doco(std::list < DOCO* > docolist, int docoid)
{
for (std::list<DOCO*>::iterator it = docolist.begin(); it != docolist.end(); )
{
if ((*it)->id == docoid)
{
delete * it;
it = docolist.erase(it);
std::cerr << "item erased\n";
}
else
{
++it;
}
}
std::cerr << "leaving kill\n";
return true;
}
【问题讨论】:
-
您能给我们提供一个minimal reproducible example 来重现该行为吗?乍一看,您的代码看起来还不错。
-
当您尝试从列表中删除它时,不要在顶部条件块中声明本地“删除 * 它”,它显然不存在。请参阅en.cppreference.com/w/cpp/container/list/erase 中的示例
-
您要擦除的列表是原始列表的副本,因为该函数是通过值传递调用的。
-
啊等等,我要快。您正在处理列表的副本。您必须通过引用传递它:
bool DOCO::kill_doco(std::list < DOCO* >& docolist, int docoid) -
“一项学校作业(我知道这里不应该这样做” - 不让别人帮你做作业,但会问一个从你的作业中产生的具体问题很好。