Say hello to StaticVector!

September 20, 2009

I present you the second addition to my Git-based collection of smaller code pieces (which now also has a very simple homepage).

This time, I show you a generic container class. There is already a big bunch of container classes in Qt, but I had to make one that fits my needs: the StaticVector.

Its API and purpose is similar to QVector, but it behaves quite differently: A StaticVector does never reallocate or resize its data unless it’s explicity told to do so. Also, any copy of a StaticVector will be read-only, because the data is implicitly shared for performance reasons, but write operations would require the copy to detach from the original data (which is an implicit reallocation, which is forbidden).

The usecase for this is quite simple: In Kolf, we are regularly passing big data arrays to OpenGL and ODE. And passing big arrays to methods from C libraries almost always requires one to pass a base pointer and a size, i.e., two parameters. With such data encapsuled into classes (such as QImage), you might end up with a situation like the following:


void passData(uint* data, int size);

class MyContainer
{
QVector m_payload;
public:
QVector payload() const { return m_data; }
//...
};

MyContainer container;
//...
passData(container.payload().data(), container.payload().size());

This is asking for trouble. The two calls to MyContainer::payload() in the last line create two temporary objects. The latter one is not problematic, because QVector::size() is a const method, but QVector::data() is a non-const method (because the C library wants a modifiable pointer). Calling it causes this temporary QVector instance to detach from the original payload, i.e., allocate new memory and copy the data to there. The C library will remember the pointer to this newly allocated data. After the passData method call, the temporary QVector instances are deleted, which causes the newly allocated data to be deallocated. When the C library tries to access this data later on, we’ll get a SIGSEGV or even uglier things.

That’s where StaticVector comes in. If you substitute QVector with StaticVector in the above example, everything works well, because the temporary StaticVector instances are read-only, but (for this usecase) may return a non-const raw data pointer.

If you ever need to use C libraries which want non-const data pointers, StaticVector might be a good choice for you, because it allows to get this non-const pointer even from const or read-only StaticVector instances, while it minimises misuse of this pointer as much as possible.

Advertisements

3 Responses to “Say hello to StaticVector!”

  1. peppedx Says:

    Hi,

    I think that this template colud be quite useful, especially for people like me that work in mixed C/C++ environments,

    I have one question, It’s my fault or the only dependence from QT is given by Q_ASSERT?
    In that case why don’t you use ?

    Thanks,
    G.

    • Stefan Majewsky Says:

      Seems like the WordPress editor ate your recommendation. What exactly do you mean? (You can also clone the repo, do the changes there, and send me a patch if you like.)

      • peppedx Says:

        Ops! I’m sorry I haven’t noticed!

        Anyway I have only suggested the switch from Q_ASSERT to assert.

        In any I think I will try your static vector soon .


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s