Natulux
Natulux

Reputation: 187

Is using a pointer to an elements in an vector dangerous?

I have an vector, filled with objects:

std::vector<MyClass> vec;
vec.push_back(MyClass("Hi", 10)); //example, could be any class

Later, when it is filled, I want to access it:

for(unsigned int i = 0; i < vec.size(); i++)
{
  MyClass *c = & vec.at(i); // <--- HERE
  if(c)                     // <--- AND HERE 
  {
    c->memberOfMyClass = x;
  }
}

Is using c more dangerous than using vec.at(i) directly? Do I need the protection with if(c)? Can c be nullptr? I guess no, because the vector does take object, not pointer to objects.

Upvotes: 3

Views: 226

Answers (4)

it's a better way to access, if you have to do multiple access to the same element of the vector.

Upvotes: 0

eerorika
eerorika

Reputation: 238351

Is using c more dangerous than using vec.at(i) directly?

Not in the example. It is unnecessarily complex however.

Can c be nullptr?

Not in the example.

Do I need the protection with if(c)?

No; see above.

Is using a pointer to an elements in an vector dangerous?

Using pointer - or any other form of indirection - in general can be "dangerous" in the sense that the lifetimes of the pointer and the pointed object are separate. Therefore you must be aware of what the lifetime of the pointed object is because if it is shorter than the pointer, then pointer will be left "dangling". Assuming the lifetime wrongly can lead to undefined behaviour.

An example of a broken program:

std::vector<MyClass> vec{
    {"Hi", 10},
};
MyClass *c = &vec.at(0);          // OK
vec.emplace_back("Hi again", 42); // c may be invalid now
c->memberOfMyClass = x;           // potential undefined behaviour

Upvotes: 2

molbdnilo
molbdnilo

Reputation: 66371

A pointer that you acquire with & can't be null, so there is no danger and no point in checking.

(You might be thinking about how a pointer to an element may become invalid if you add or remove elements to the vector, but it will never become null and you can't detect this.)

It's common to use a reference in this situation:

MyClass& c = vec.at(i);
c.member = x;

but with your specific loop, consider using a range loop instead:

for (auto& c : vec)
{
    c.member = x;
}

Upvotes: 2

sklott
sklott

Reputation: 2849

First of all its better to use reference instead of pointer.

You don't need to check pointer if you are sure you have at least i items in vector.

You can use reference/pointer as long as iterators is not invalidated. Read section "Iterator invalidation" here: https://en.cppreference.com/w/cpp/container/vector

Upvotes: 0

Related Questions