Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 581
RRR Avatar asked Sep 12 '13 08:09

RRR


People also ask

How do you assign a value to an array vector in C++?

The syntax for assigning values from an array or list: vectorname. assign(arr, arr + size) Parameters: arr - the array which is to be assigned to a vector size - number of elements from the beginning which has to be assigned.

Can you memcpy into a vector?

You can use the Use memcpy for vector assignment parameter to optimize generated code for vector assignments by replacing for loops with memcpy function calls. The memcpy function is more efficient than for -loop controlled element assignment for large data sets. This optimization improves execution speed.

How does std::vector work internally?

It will allocate a bigger chunk of memory on heap i.e. almost double the size of previously allocated. 2.) Then it copies all the elements from old memory location to new one. Yes it copies them, so in case our elements are user defined objects then their copy constructor will be called.


1 Answers

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);
like image 70
bitmask Avatar answered Nov 14 '22 21:11

bitmask