If I have something like the code below, where I pass a vector pointer (e.g. it can be null), then in the called function I add items to the vector, is there danger that my vector pointer can become invalid? The same goes for passing by reference. Since vector is guaranteed to be contiguous in memory and will reallocate as needed is there danger that I could get a dangling pointer because the vector is relocated in memory? The code below is trivial but what if myVecFunc was adding a million values, or some large objects? I've seen library code that follows this pattern but it seems like you could run into trouble by doing this? EDIT: Edited code to do *mVec->push_back(someNumber)
void myVecFunc(std::vector<double>* myVec)
{
if (myVec != nullptr)
{
myVec->push_back(someNumber);
}
}
int main(int argc, char* argv[])
{
std::vector<double> myVec;
myVecFunc(&myVec);
}
You have two fundamental misunderstandings.
First, passing a pointer to a function: Function arguments are passed by value (unless you use references), pointers are no exception:
void foo(int*);
// usage
int* x = nullptr;
foo(x);
assert( x == nullptr);
There is no way the assert could fail, because foo
cannot modify x
. In your example myVecFunc
cannot modify the addressof myVec
. The memory location of an object is tied to its identity. During lifetime it doesn't change. If you copy a vector to a different location, you get a copy.
Next std::vector
. A vector internally stores a pointer to dynamically allocated memory used for the elements. The memory is properly managed by the vector. For example, you can copy a vector and it will copy the elements. You can pass a vector by pointer or by reference, no problem at all.
What can happen on a reallocation that the pointer that the vector stores internally gets a different value. Hence this code should not be written like this:
std::vector<int> foo(2); // vector of size 2
int* ptr = foo.data(); // pointer to the internal array
foo.push_back(42); // iterators and pointers are invalidated
std::cout << *ptr; // DO NOT DEREFERENCE THE INVALID POINTER !
In summary: there is nothing wrong in the code you show. However, you should only pass arguments by pointer when nullptr
is a valid input. Otherwise use a reference.