1

I keep hitting this weird std::vector behavior which I can't make any sense of.

Roughly, the code looks like

#include <iostream>
#include <vector>

class MyClass{
public:
  MyClass():
    v_(),
    w_(init_w())
  {};

  ~MyClass()
  {};

  std::vector<int*> init_w()
  {
    v_.resize(4096);
    return v_;
  };
private:
  std::vector<int*> w_;
  std::vector<int*> v_;
};

int main()
{
  MyClass a;
}

Running this gives me a bad segfault at the resize. If a lower value is chosen for the resize instead, the code might not segfault at all.

Update: The problem is that, contrary to what the initializer list indicates, w_ get initialized before v_. Hence, in init_w(), v_ state is undefined. Reverting the order of v_ and w_ in the declarations fixes the problem.

Nico Schlömer
  • 53,797
  • 27
  • 201
  • 249
  • 3
    Please give a minimal, compiling example that displays the problem. – TemplateRex Jul 26 '12 at 18:40
  • @rhalbersma I've struggled several hours to break down the code into something small and easy that fails, but didn't succeed. I'm aware of the fact that this makes it hard to find the error. – Nico Schlömer Jul 26 '12 at 18:43
  • @Nico: Not hard, impossible. -1 from me I'm afraid. – Troubadour Jul 26 '12 at 18:44
  • @Nico: Your sample code (plus a `typedef int mytype;`, to make it compile) runs fine for me with g++ 4.2.1; valgrind didn't find any issues either. I think the relevant code is missing. – Frerich Raabe Jul 26 '12 at 18:44
  • @chris I've got no idea. `mytype` is a type from a larger library I have no insight in. Might there be a problem, though? – Nico Schlömer Jul 26 '12 at 18:44
  • 1
    @chris It shouldn't matter, since the vector element type is a pointer. – cdhowie Jul 26 '12 at 18:44
  • @Nico this makes it impossible to find the error. – Luchian Grigore Jul 26 '12 at 18:44
  • @Nico: You could test whether `mytype` triggers the issue by temporarily replacing it with, say, `int`. Furthermore, looking at line 591 in your `stl_vector.h` might give some hint as to what's triggering the crash. – Frerich Raabe Jul 26 '12 at 18:46
  • @cdhowie, My mind jumbled it around a bit. You're right. – chris Jul 26 '12 at 18:52
  • 1
    An answer to [this similar question](http://stackoverflow.com/questions/2612447/pinpointing-conditional-jump-or-move-depends-on-uninitialized-values-valgrin) might help you pinpoint the source of the segfault. – Blastfurnace Jul 26 '12 at 18:52
  • Debugging can be hard and frustrating. Make sure you have good tools: http://stackoverflow.com/questions/426569/why-is-debugging-better-in-an-ide – TemplateRex Jul 26 '12 at 19:07
  • Replacing `mytype` with `char` or any other POD, this compiles and runs for me. – Matt Phillips Jul 26 '12 at 19:17
  • I updated the question and added the solution. Thanks again everyone for helping me out! – Nico Schlömer Jul 26 '12 at 23:25

1 Answers1

2

The problem is that, contrary to what the initializer list indicates, w_ get initialized before v_

You inferred that to be the case, but in reality it is not. The order of the list is not relevant; the order of declaration in the class is. So, your initialization list should mimic the declaring order if you want to see how the members are actually being initialized.

My question to you is; why are you using a vector of pointers to begin with? Do you realize that you need to delete every element in the list before your object goes out of scope or suffer a memory leak?

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • Indeed, it's the order of declaration. Some compilers even warn if the items are declared in another order that they are initialized. The reason why I'm working with vectors of pointers is that the library I use requires that format. In particular, the vector filling routines I call have `std::vector` as argument. – Nico Schlömer Jul 26 '12 at 23:59
  • how does this answer `answers` the question ? – Jay D Jul 27 '12 at 00:00
  • 1
    @Nico: Ah, ok, just be careful with that then (that stinks, but oh well, not much you can do about it.) – Ed S. Jul 27 '12 at 00:00
  • @JayD: The initialization order is the problem. `init_w()` calls `_v.resize()` before `_v` is initialized. – Ed S. Jul 27 '12 at 00:01