Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding NULL pointers in std vectors

I'm working with vectors and at some point there will be NULL entries; I want to erase all NULL occurrences within the given vectors. My approach so far is not working:

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]);

Where

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

are the vectors. I have tried casting to a type (Flit*)NULL/(Flit*)0 but with no success.

Any help will be greatly appreciated.

like image 488
Sebi Avatar asked Jul 12 '12 21:07

Sebi


2 Answers

Use the Erase-Remove idiom to remove elements based on a predicate from a container.

In your case:

// 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));

Your current approach isn't working, because vector::erase expects an iterator to an element of the vector and not a value of the stored type.

Frankly, what you are doing seems a little bit strange. You shouldn't store pointers, but values in containers. If you require nullable values, use a Maybe class such as boost::optional.

like image 135
pmr Avatar answered Sep 28 '22 08:09

pmr


pmr is absolutely correct that you should be using remove followed by erase, and that this is the most important mistake in the code. However, the mistake that's actually causing the error message you report is as follows:

Your variables sent_pkt_list and sent_flit_list are pointers to vectors, not vectors. Therefore, when you say something like sent_pkt_list[i], this is doing C-style array indexing, not vector indexing. The value of sent_pkt_list[i] is a (doubtless nonsensical because it's effectively dereferencing a bogus pointer) vector<Packet*>, not a Packet*. So you then try to compare that against NULL, which of course doesn't work.

like image 21
Gareth McCaughan Avatar answered Sep 28 '22 06:09

Gareth McCaughan