【问题标题】:Finding NULL pointers in std vectors在标准向量中查找 NULL 指针
【发布时间】:2012-07-12 17:35:39
【问题描述】:

我正在使用向量,在某些时候会有 NULL 条目;我想删除给定向量中的所有 NULL 出现。到目前为止,我的方法不起作用:

for(int i = sent_flit_list->size() - 1; i >= 0; i--)
if(sent_flit_list[i] == NULL)
    sent_flit_list->erase(sent_flit_list[i]);

for(int i = sent_pkt_list->size() - 1; i >= 0; i--)
if(sent_pkt_list[i] == NULL)
    sent_pkt_list->erase(sent_pkt_list[i]);

在哪里

vector<Flit*> *sent_flit_list;
vector<Packet*> *sent_pkt_list;

是向量。我尝试转换为 (Flit*)NULL/(Flit*)0 类型,但没有成功。

任何帮助将不胜感激。

【问题讨论】:

  • “不工作”到底是什么意思?发生什么了?它与你想要发生的有什么不同?
  • IIRC,vector::erase 将迭代器,而不是值作为参数。
  • @Gareth 给出错误,例如错误 C2678: binary '==' : no operator found... 我只是想删除那些向量中指向 NULL 的所有内容。
  • 您真的应该为此使用remove,而不是显式循环。我认为你的问题的直接原因是sent_flit_listsent_pkt_list指向向量的指针,而不是向量,所以当你说例如sent_pkt_list[i] 索引操作不是你想的那样。 (这不是代码的唯一问题,而是导致该错误消息的问题。)
  • 另一个到目前为止没有人提到的提示,如果这是错误的,请删除:我们不应该删除元素并在没有迭代器的情况下循环遍历向量。因为假设您在 std::vector a 中有 2 个值,您像您一样使用索引遍历向量,现在擦除位置 1 的值,2 索引现在是错误的,因为向量缩小了...始终使用迭代器 (it) 和使用it=a.erase(it)

标签: c++ pointers stl null


【解决方案1】:

使用Erase-Remove idiom 从容器中删除基于谓词的元素。

在你的情况下:

// with a predicate
my_vec.erase(std::remove_if(begin(my_vec), end(my_vec), 
                           [](Flit* x) { return x == nullptr; }), 
             end(my_vec));

// with a value value
my_vec.erase(std::remove(begin(my_vec), end(my_vec), nullptr),
             end(my_vec));

您当前的方法不起作用,因为vector::erase 需要一个指向向量元素的迭代器,而不是存储类型的值。

坦率地说,你所做的似乎有点奇怪。您不应将指针存储在容器中,而应将值存储在容器中。如果您需要 nullable 值,请使用 Maybe 类,例如 boost::optional

【讨论】:

  • 指针向量有什么问题?甚至是智能指针?
  • @Johan:boost::optional 之类的东西会断言它已初始化,这与可能的空指针问题不同。但是,如果您有大型对象,那么Maybe 类并不总是一种选择。
  • @Johan:其实没什么。有时,这是正确的做法。但是,OP 使用了太多的它们被认为是正常的(指向指针向量的指针,两次)。当然,我们不知道确切的情况,但是 OP 使用了那么多指针,再加上他是初学者甚至不知道 std::remove,这表明他有点过于热心了它们,而且可能根本不需要它们。
  • 但在erase() 中使用end() 迭代器是非法的:提供给erase() 的所有迭代器都必须有效且可取消引用。
【解决方案2】:

pmr 绝对正确,您应该使用remove 后跟erase,这是代码中最重要的错误。但是,实际上导致您报告的错误消息的错误如下:

您的变量sent_pkt_listsent_flit_list指向向量的指针,而不是向量。因此,当您说sent_pkt_list[i] 之类的内容时,这是在执行 C 样式的数组索引,而不是向量索引。 sent_pkt_list[i] 的值是 vector&lt;Packet*&gt;(毫无疑问是荒谬的,因为它有效地解除了对虚假指针的引用)vector&lt;Packet*&gt;,而不是 Packet*。因此,您然后尝试将其与 NULL 进行比较,这当然是行不通的。

【讨论】:

  • 就个人而言,我认为 pmr 的答案应该得到支持(因为,真的,这是提问者需要知道的),我的应该被接受(因为它恰好解释了提问者所困扰的具体错误)。但是生命太短暂了,不必担心任何给定的 SO 答案是否已被投票和接受的公众完全最优地对待!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多