Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixed allocation std::vector

I'm an embedded software developer and as such I can't always use all the nice C++ features. One of the most difficult things is avoiding dynamic memory allocation as it is somewhat universal with all STL containers.

The std::vector is however very useful when working with variable datasets. The problem though is that the allocation(e.g. std::reserve) isn't done at initialization or fixed. This means that memory fragmentation can occur when a copy occurs.

It would be great to have every vector have an allocated memory space which is the max size the vector can grow to. This would create deterministic behaviour and make it possible to map the memory usage of the microcontroller at compilation time. A call to push_back when the vector is at it's max size would create a std::bad_alloc.

I have read that an alternative version of std::allocator can be written to create new allocation behaviour. Would it be possible to create this kind of behaviour with std::allocator or would an alternative solution be a better fit?

I would really like to keep using the STL libraries and amend to them instead of recreating my own vector as I'm more likely to make mistakes than their implementation.

sidenote #1:

I can't use std::array as 1: it isn't provided by my compiler and 2: it does have a static allocation but I then still have to manage the boundary between my data and buffer inside the std::array. This means rewriting a std::vector with my allocation properties which is what I'm trying to get away from.

like image 522
Tarick Welling Avatar asked Jul 08 '19 12:07

Tarick Welling


People also ask

Is std::vector heap allocated?

std::vector typically allocates memory on the heap (unless you override this behavior with your own allocator). The std::vector class abstracts memory management, as it grows and shrinks automatically if elements are added or removed.

Are vectors fixed size in C++?

The size of a std::vector is dynamic - it will allocate required storage dynamically, and you cannot limit the size and enforce an error. You can however reserve a certain size, and then add elements up that size before it needs to allocate new storage.

How does std::vector allocate memory?

Vectors are assigned memory in blocks of contiguous locations. When the memory allocated for the vector falls short of storing new elements, a new memory block is allocated to vector and all elements are copied from the old location to the new location. This reallocation of elements helps vectors to grow when required.

Is std::vector slower than array?

A std::vector can never be faster than an array, as it has (a pointer to the first element of) an array as one of its data members. But the difference in run-time speed is slim and absent in any non-trivial program. One reason for this myth to persist, are examples that compare raw arrays with mis-used std::vectors.


2 Answers

You can implement or reuse boost's static_vector; A variable-size array container with fixed capacity.

like image 119
Michael Chourdakis Avatar answered Oct 11 '22 12:10

Michael Chourdakis


You can always use a C-style array (same as underlying in std::array) as vectors aren't supposed to be static

int arr[5]; // static array of 5 integers

To have it more useful you can wrap it in a class template to hide the C-style Example:

template<class type, std::size_t capacaty>
class StaticVector {
    private:
        type arr[capacaty];
        std::size_t m_size;
    public:
        StaticVector() : m_size(0) {}

        type at(std::size_t index) {
            if (index >=0 && index < m_size) {
                return arr[index];
            }

            return type();
        }

        void remove(std::size_t index) {
            if (index >=0 && index < m_size) {
                for (std::size_t i=index; i < m_size-1; i++) {
                    arr[i] = arr[i+1];
                }
                m_size--;
            }
        }

        void push_back(type val) {
            if (m_size < capacaty) {
                arr[m_size] = val;
                m_size++;
            }
        }

        std::size_t size() {
            return m_size;
        }
};

Example with it in use: https://onlinegdb.com/BkBgSTlZH

like image 21
DColt Avatar answered Oct 11 '22 11:10

DColt