1

I am using a vector but for a number of reasons, referring to individual elements using pointers. The problem is that when I add elements, the vector resizes and may move the elements to another larger memory address. This invalidates my pointers.

To avoid the reallocation, I call vector<T>::reserve before using the vector. However there are instances where I have not reserved enough space. In this instance I would like the vector to assert or throw an exception rather than trying to silently resize.

Is there any way to do this using vectors or another data structure? Can I use C99 variable length arrays and if so, how do I initialized one to the correct length in my constructor? Or do I need to roll out my own explicitly resizable vector?

1
  • 2
    Not quite a duplicate, but a similar question I remember, which might have valuable suggestions: stackoverflow.com/questions/12674749/… (and btw, VLAs are C99). Commented Apr 11, 2013 at 10:04

2 Answers 2

2

If you check much space you have reserved, you could simply solve this "In this instance I would like the vector to assert or throw an exception rather than trying to silently resize." with

if (v.size() == v.capacity()) throw ... 

You could write a function like this:

template <typename T>
void safe_vector_push_back(std::vector<T>& v, const T &e)
{
   if (v.size() == v.capacity()) throw ... 
   v.push_back(e);
}

Another possible method would of course be to NOT store pointers to content in your vector at all. Just store the index into the vector. That way, the vector can resize as much as it likes, and nothing will go wrong.

It is generally a bad idea to store pointers to data inside another object (in this case, vector is an object).

Sign up to request clarification or add additional context in comments.

6 Comments

You don't even have to remember it, you can use std::vector::capacity.
Except, I need to run this test every time I call a push_back, I would like this to be defined I one place only.
@doron you could create your own vector-like container, that wraps an std::vector and applies these checks where required.
@doron: I have updated the answer with an example of code that does it in one place. You just end up with a function call instead of a method call on the vector.
Grr, I just wrote pretty much the same code and came back to post it.
|
1

Inheritance is your friend:

template<typename T, typename A = std::allocator<T>>
class myvector : public std::vector<T, A>
{
    typedef std::vector<T,A> base_t;
public:
    myvector()
    {
    }

    myvector(size_t size) : base_t(size)
    {
    }
    void push_back(T val)
    {
        if(capacity() == size())
            throw "no more room";
        base_t::push_back(val);
    }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.