1

I have some class where I want to use a large amount of vectors.

class Bar {
    Bar ();
    std::vector<Foo> * _grid;
    void someFunction ();
}

Bar::Bar () {
    _grid = (std::vector<Foo> *)malloc(_gridSize * sizeof(std::vector<Foo>);
    memset(_grid, 0, _gridSize * sizeof(std::vector<Foo>);
}

void Bar::someFunction () {
    int index = 0;
    std::vector<Foo> someVariable = _grid[index];
}

However, as soon as I call someFunction(), I get a vector iterators incompatible error message as soon as there is some content in _grid[index]. If the vector is empty, it works.

I've read about the error message being produced by invalidated iterators, however, since I don't change anything on the vectors at this point, I don't get what is wrong here.

Etan
  • 17,014
  • 17
  • 89
  • 148
  • 3
    Why in the world are you using `malloc`? Your vector isn't being constructed! – Fred Larson Dec 08 '10 at 03:25
  • The strange thing about it was that push_back etc worked and visual studio correctly has shown it with capacity and size ^^. Forgot the constructor. – Etan Dec 08 '10 at 03:46
  • "I have some class where I want to use a large amount of vectors." Which amount you are apparently determining at runtime. Uhhh... why not just use a vector of vectors? Did you somehow forget what vectors are **for** in the middle of using them? :) – Karl Knechtel Dec 08 '10 at 05:02
  • As for why it "seems to work", you got lucky that `memset` **just happened** to do **something close enough** to "the right thing" for **your particular implementation of** std::vector to fool your debugger. Please **never** use this function in C++. Even if you just want to zero out an array of `char` s. In modern C++, the functionality you want is spelled `std::fill` and lives in ``. Although that's for the general case; you can get the constructors called by just using the constructor for the vector of vectors, or its `.resize()` member function. – Karl Knechtel Dec 08 '10 at 05:04
  • Ah, problem with vectors of vectors and then calling resize is that it takes about 10 seconds since I have about 100k vectors. @Karl: Exactly this was the thing which confused me and misguided me from the simple thing that the constructor was missing. Combine this with google results about iterator invalidation and you get my problem ;-) Everything pointed away from the obvious solution. – Etan Dec 08 '10 at 05:18
  • ... and how many `Foo` s do you have, to start off, in each vector? Do you want the storage to be kept "rectangular", i.e. every vector is the same length? What are you **really** trying to do? – Karl Knechtel Dec 08 '10 at 05:21
  • I have multiple points in 3d-space which I want to put in voxels. Since I cannot use a predefined grid, I use an infinite one and use some hash table where each position maps into. This way, all points in the same voxel end up in the same bucket. The grid is exactly this hash table. Not every vector has the same length. – Etan Dec 08 '10 at 05:25

1 Answers1

4

You almost certainly don't want to dynamically allocate the vector; just include it as a member of the class:

class Bar { 
    std::vector<Foo> _grid;
};

If you really want to dynamically allocate the vector, you want to use new, which constructs the vector. As it is written now, you malloc space for the vector and set all the bytes occupied by the vector to zero. You never call the std::vector constructor for the allocated object, so you can't use it as a std::vector.

Make sure you have a good introductory C++ book from which to learn the language. If you don't understand the C++ memory model and object model, there is now way you'll be able to write correct C++ code.

Community
  • 1
  • 1
James McNellis
  • 348,265
  • 75
  • 913
  • 977