For several reasons:
- std::vector initializes the entire buffer. This is bad, not only
because of the time it takes to initialize the buffer, but also
because it requires the OS to map all pages into physical memory even
if they never end up being used.
- You can't shrink the memory footprint of a std::vector without
copying the data.
I'm aware of std::vector, I love it and I use it all the time, but
it's not appropriate for this situation. It's a video application on
an embedded system, and it's one of those areas of the code that I've
profiled and determined that I need maximum performance with minimal
memory overhead. With a few minor changes, std::vector could fit the
bill. But it doesn't.
This has taken more time than it would have taken to write my own RAII
wrapper, so I guess I'll do that. Thanks anyway.
Good move. So what I'm about to say is probably too late for your
needs. But I'm posting it anyway because it might help the next guy.
The new C++0X std::unique_ptr might be a good tool to use in this
situation. You might use it like:
std::unique_ptr<int[]> v(new int[N]);
v[0] = ...
v[1] = ...
....
If you really need to work with malloc/free, that can be done with:
std::unique_ptr<int[], void(*)(void*)>
v((int*)std::malloc(N*sizeof(int)), std::free);
v[0] = ...
v[1] = ...
....
You need to keep track of N yourself. std::unique_ptr (and N) might
be handy members of that wrapper.
Advantages of unique_ptr:
* It maintains unique_ownership of the pointer (enforced at compile
time). It can't be copied (it can be moved in c++0x).
* You still get the handy array access syntax.
* You control the allocation and initialization of the buffer.
* The version using new has an overhead of 1 word. The version using
malloc/free has an overhead of 2 words.
* The malloc version can work with realloc:
v.reset(std::realloc(v.release(), new_size)));
Though if realloc fails (returns 0), the above will leak. If that is
a danger that you want to guard against on your platform, an extra
temp should do it:
std::unique_ptr<int[], void(*)(void*)> tmp(std::realloc(v.get(),
new_size), std::free);
if (!tmp)
// deal with out of memory
v.swap(tmp);
tmp.release();
You probably don't have std::unique_ptr available in your toolbox at
the moment. I believe there's a boost version that will work fine
today.
-Howard