Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using vector<char> as a buffer without initializing it on resize()

Tags:

c++

c++11

boost

I want to use vector<char> as a buffer. The interface is perfect for my needs, but there's a performance penalty when resizing it beyond its current size, since the memory is initialized. I don't need the initialization, since the data will be overwritten in any case by some third-party C functions. Is there a way or a specific allocator to avoid the initialization step? Note that I do want to use resize(), not other tricks like reserve() and capacity(), because I need size() to always represent the significative size of my "buffer" at any moment, while capacity() might be greater than its size after a resize(), so, again, I cannot rely on capacity() as a significative information for my application. Furthemore, the (new) size of the vector is never known in advance, so I cannot use std::array. If vector cannot be configured that way, I'd like to know what kind of container or allocator I could use instead of vector<char, std::alloc>. The only requirement is that the alternative to vector must at most be based on STL or Boost. I have access to C++11.

like image 759
Martin Avatar asked Mar 05 '13 09:03

Martin


People also ask

What happens when vector is resized?

vector::resize() The function alters the container's content in actual by inserting or deleting the elements from it. It happens so, If the given value of n is less than the size at present then extra elements are demolished.

How do you initialize and resize a vector in C++?

The C++ function std::vector::resize() changes the size of vector. If n is smaller than current size then extra elements are destroyed. If n is greater than current container size then new elements are inserted at the end of vector. If val is specified then new elements are initialed with val.

Does vector clear reset size?

vector::clear() clear() function is used to remove all the elements of the vector container, thus making it size 0.

Is all data stored in a vector lost when resized?

Vector images don't use pixels. They're created with mathematical equations, lines, and curves — using points fixed on a grid — which means images can be made infinitely larger (or smaller) without losing resolution. Basically, vectors don't lose quality when resized.


2 Answers

It is a known issue that initialization can not be turned off even explicitly for std::vector.

People normally implement their own pod_vector<> that does not do any initialization of the elements.

Another way is to create a type which is layout-compatible with char, whose constructor does nothing:

struct NoInitChar {     char value;     NoInitChar() noexcept {         // do nothing         static_assert(sizeof *this == sizeof value, "invalid size");         static_assert(__alignof *this == __alignof value, "invalid alignment");     } };  int main() {     std::vector<NoInitChar> v;     v.resize(10); // calls NoInitChar() which does not initialize      // Look ma, no reinterpret_cast<>!     char* beg = &v.front().value;     char* end = beg + v.size(); } 
like image 58
Maxim Egorushkin Avatar answered Sep 26 '22 07:09

Maxim Egorushkin


There's nothing in the standard library that meets your requirements, and nothing I know of in boost either.

There are three reasonable options I can think of:

  • Stick with std::vector for now, leave a comment in the code and come back to it if this ever causes a bottleneck in your application.
  • Use a custom allocator with empty construct/destroy methods - and hope your optimiser will be smart enough to remove any calls to them.
  • Create a wrapper around a a dynamically allocated array, implementing only the minimal functionality that you require.
like image 34
JoeG Avatar answered Sep 25 '22 07:09

JoeG