Jump to content
  • Advertisement
Sign in to follow this  
shadowman131

Why use std::vector?

This topic is 3988 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I really like std::vector, I love the concept of a dynamic array of course. However, my one gripe is the following snippet:

#include <vector>
#include <stdio.h>

static int constructs = 0;
static int destructs = 0;
static int copies = 0;
class Copyable
{
public:
    Copyable() { constructs++; }
    Copyable(const Copyable&) { copies++; }
    ~Copyable() { destructs++; }
};

int main(int argc, char* argv[])
{
    std::vector<Copyable> vec;
    for (int i = 0; i < 10000; i++) {
        vec.push_back(Copyable());
    }
    printf("%i constructs\n%i copies\n%i destructs\n", constructs, copies, destructs);
    return 0;
}



Prints out: 10000 constructs 34308 copies 34308 destructs Note that those precursor the scope exit; i.e. there would be total 44308 destructs after vector destruction. I find these copies and destructs to be excessive when it is easy to make something that can do similar with only 10000 total constructs and destructs with 0 copies; and it could still possess the same functionality as std::vector. Maybe I'm missing some advantage to this; but it seems a lot of overhead, particularly with user-defined classes! -Walt

Share this post


Link to post
Share on other sites
Advertisement
well, if you would create the vector with starting memory of size 10000, it would have only 10000 constructions and 10000 copies, or so.. :)

Share this post


Link to post
Share on other sites
Is it a bottleneck?

If not, don't worry about it. Unless you have highly specialized needs, you can't implement something with the same characteristics that will not copy it's contents the way vector does to resize. You can't simply memcpy the data, that isn't safe for non-POD types.

Besides, simple solution? reserve(), std::vector<Copyable*>. Maybe an allocator if you really need to. There are lots of ways to improve the performance of SC++L containers in sane ways.

Share this post


Link to post
Share on other sites
To add to what's already been said, copying elements during resizing is the only sane way to grow the array, memcpy is not always suitable for custom types. Use reserve if you know how big it will need to be, or store pointers.

Share this post


Link to post
Share on other sites
Quote:
Original post by jpetrie
Is it a bottleneck?


A huge one, to be exact :) And reserve() only really works if you know how big you want your array, right?

Quote:
You can't simply memcpy the data, that isn't safe for non-POD types.


Please explain this; it's not that I don't believe you, but how does the following form for say non-POD object A not work:


push_back(A());
//Constructs A inside vector
push_back(A());
//Tests for size - resize required
//Allocate (malloc) size of new array
//memcpy() old array to new array
//free() old array
//Old objects should still exist in their proper form,
//as they were constructed validly, and all of their contents
//were properly transferred?
//Construct A inside vector



-Walt

Share this post


Link to post
Share on other sites
Well if you yourself have concluded that std::vector isn't suitable, have you thought about std::list?

Have you thought about how you can predict the kind of size to reserve?

Share this post


Link to post
Share on other sites
Change A() to std::string("Hey we have a long string!!!") and you'll find out, in the form of a crash. As soon as the type you are storing in the vector has a pointer to dynamic memory, you're going to run into problems when using memcpy. That's why standard containers use copy constructors and such, to ensure they work with every type(provided they implement a proper copy constructor, etc)

Share this post


Link to post
Share on other sites
Quote:
Original post by shadowman131
Please explain this; it's not that I don't believe you, but how does the following form for say non-POD object A not work:


There are two reasons to this. The most elementary one is that memcpy doesn't do what you seem to think it does.

memcpy is a function which copies a block of bytes from one location in memory to another. It doesn't copy PODs, it doesn't copy integers, it doesn't copy non-PODs, the only thing it can copy is bytes.

The C++ Standard lets you reinterpret a POD object or array of POD objects as a sequence of bytes, use memcpy on that sequence of bytes, and then reinterpret the destination sequence of bytes back as a POD object or array of POD objects. The C++ Standard explicitly forbids you from reinterpreting a non-POD object (or an array of such objects) as a sequence of bytes—attempting to do so against this interdiction will yield a sequence of bytes which may or may not be a complete representation of the object (i.e. some parts of the object might not appear in the representation). And, even then, the C++ Standard explicitly forbids you from reinterpreting a sequence of bytes as a non-POD object—attempting to do so will result in outright undefined behaviour, and your program may crash, do what you think it should do, overwrite random memory, or launch a nuclear missile at a cow ranch in Alaska.

The second reason is that it's not practical. Some objects may be doing something important with their position in memory—perhaps they registered themselves with a manager, or perhaps they are keeping a pointer or reference to one of their own members. When such objects are stored in a container, they should be notified that they are about to be moved around—something which a copy constructor and destructor will achieve with decent performance. In short, even if converting non-POD objects to a byte sequence worked (which it doesn't), your container will still cause bugs when self-referring objects are stored in it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!