I am working with STL library and my goal is to minimize the data reallocation cases. I was wndering, does
std::vector::assign(size_type n, const value_type& val)
reallocated the data if the size is not changed or does is actually just assign the new values (for example, using operator=) ?
The STL documentation at http://www.cplusplus.com/ sais the following (C++98):
In the fill version (2), the new contents are n elements, each initialized to a copy of val. If a reallocation happens,the storage needed is allocated using the internal allocator.
Any elements held in the container before the call are destroyed and replaced by newly constructed elements (no assignments of elements take place). This causes an automatic reallocation of the allocated storage space if -and only if- the new vector size surpasses the current vector capacity.
The phrase "no assignments of elements take place" make it all a little confusing.
So for example, I want to have a vector of classes (for example, cv::Vec3i of OpenCV). Does this mean, that
EDIT: the whole purpose of using assign in this case is to set all values in the vector to 0 (in case I have std::vector< cv::Vec3i > v). It will be done many-many times. The size of std::vector itself will not be changed.
what i want to do (in a shorter way) is the following:
for(int i=0; i<v.size(); i++)
for(int j=0; j<3; j++)
v[i][j] = 0;
right now I am interested in C++98
std::vector.assign(...)
does not reallocate the vector if it does not have to grow it. Still, it must copy the actual element.
If you want to know what the standard guarantees, look in the standard: C++11 standard plus minor editorial changes.
I assume that you have a vector filled with some data and you call an assign on it, this will:
So if your class allocates some memory you have to:
Reallocations happen when the size exceed the allocated memory (vector capacity). You can prevent this with a call to reserve(). However I think that assign() is smart enough to allocate all the memory it needs (if this is more than the already allocated) before starting to fill the vector and after having cleared it.
You may want to avoid reallocations because of their cost, but if you are trying to avoid them because your objects cannot handle properly, then I strongly discourage you to put them in a vector.
The semantics of assign
are defined the standard in a quite straightforward way:
void assign(size_type n, const T& t);
Effects:
erase(begin(), end());
insert(begin(), n, t);
This means that first the destructors of the elements will be called. The copies of t
are made in what is now a raw storage left after the lifetime of the elements ended.
The requirements are that value_type
is MoveAssignable
(for when erase
doesn't erase to the end of the container and needs to move elements towards the beginning).
insert
overload used here requires that value_type
is CopyInsertable
and CopyAssignable.
In any case, vector is oblivious to how your class is managing its own resources. That's on you to take care of. See The Rule of Three.
As in the case of vector::resize
method,
std::vector::assign(size_type n, const value_type& val)
will initialize each element to a copy of "val" . I prefer to use resize
as it minimizes the number of object instanciations/destructions, but it does the same. Use resize
if you want to minimize the data realloc, but keep in mind the following:
While doing this is safe for certain data structures, be aware that assigning /pushing elements of a class containing pointers to dynamically allocated data (eg with a new
in the constructor) may cause havoc.
If your class dynamically allocates data then you should reimplement the YourClass::operator=
to copy the data to the new object instead of copying the pointer.
Hope that it helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.