Search code examples
c++vectorstdvector

STD::Vector- write directly to the internal array


Is the following code ok?:

std::vector<char> var;
size_t requiredSize;

getenv_s(&requiredSize, NULL, 0, "Something");
if (requiredSize == 0)
{
   return ENV_NOT_EXIST;
}
if(var.size() < requiredSize)
    var.resize(requiredSize);

// Get the value of the environment variable.
getenv_s(&requiredSize, &var[0], requiredSize, "Something");

std::string str(var.begin(),var.end());

If this code is OK, can someone please explain me how the begin() and the end() values of the var vector are updated? it looks like this code changes directly the internal array of the vector, not over the std::vector api - so how these values are updated to the actual size?


Solution

  • std::vector guarantees data to be stored contiguously, so writing to data, as long as you do not overrun the end is perfectly fine:

    From the C++11 standard section 23.3.6.1.1:

    The elements of a vector are stored contiguously, meaning that if v is a vector where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().

    However, note that resizing the vector might move the data and invalidate iterators.

    Unfortunately, the standard does not require std::vector<T>::iterator to be a raw pointer type (although it usually is). So, you cannot portably use std::vector<T>::begin() to access the first element. There is std::vector<T>::data(), which returns a pointer to the first element and which can be used for code that expects raw c-arrays.

    I suggest to rewrite your call like this:

    getenv_s(&requiredSize, var.data(), var.size(), "Something");
    if (requiredSize < var.size())
      var.resize(requiredSize);