0

I asked this question yesterday which leads to today's question (indirectly). I was getting heap corruption with the following code:

typedef struct
{
    void SetPos(const Vector2& pos)
    {
        m_var1 = pos[0];
        m_var2 = pos[1];
    }

    Vector2 GetPos() const
    {
        return Vector2(m_var1, m_var2);
    }

    union
    {
        f32 m_var1;
        f32 m_var1DiffName;
    };

    union
    {
        f32 m_var2;
    };
}StructBase;

typedef struct Struct1 : public StructBase
{
    Vec4f   m_foo;

} Struct1;

typedef struct Struct2 : public StructBase
{
    Vector2   m_foofoo;

} Struct2;

typedef struct Struct3 : public StructBase
{
    Struct3()
    {
        SetPos(Vector2(0, 0));
    }

    Struct3(const Vector2& pos)
    {
        SetPos(pos);
    }
} Struct3;

Every time I would add Struct3 to an Array (a Vector<>), the debugger would break signalling heap corruption. If I turned off the heap-corruption detection, everything would work as expected, however Visual Studio would report heap corruption when shutting down the application.

The change to Struct3 that fixed the problem:

typedef struct Struct3 : public StructBase
{
} Struct3;

Now my guess is that I was mixing a POD structure with a class disguised as a structure, but that seems like a long shot. What am I doing wrong here?

EDIT: The reason I added the constructors was so that I could add to a Vector<> Struct3 by simply passing it a Vector3<> which would construct the Struct3 and push it in to the array. So let's say the vector is: vector<Struct3> then I added Struct3's to it like so: myVec.push_back(Vector2(i, j)); (the vector<> is in a template class where the type can be any of these structures).

NOTE: I changed names around to avoid stepping on any NDA. So please ignore any style problems unless it actually affects the code. Since the code is rather simple, I pasted the whole thing, which I am sure many of you already know, is not possible all the time with production code.

Community
  • 1
  • 1
Samaursa
  • 16,527
  • 21
  • 89
  • 160
  • 1
    Struct3 to an array of *what*? The use case is what's important. – Puppy Jun 29 '11 at 19:42
  • Could you show the code where you actually use the structures (add them to an array, whatever)? – Karl Knechtel Jun 29 '11 at 19:42
  • What kind of array would you add `Struct3`-instances to? Perhaps an `std::vector`? An [SSCCE](http://sscce.org/) would be helpful. – Björn Pollex Jun 29 '11 at 19:42
  • The code you've posted, in isolation, is fine. The only way I can think of that this would lead to heap corruption is if you tried dynamically allocating a derived struct type and then deleted it through a base pointer. Alternatively, you could have some other error (perhaps not `malloc`ing enough space?) that is only triggered by using the derived types. – templatetypedef Jun 29 '11 at 19:42
  • Wait -- you're trying to store a polymorphic type in an array? C++ does not have polymorphic arrays... – Billy ONeal Jun 29 '11 at 19:42
  • @DeadeMG: Sorry I didn't make that clear. In this case the Array is a Vector<> – Samaursa Jun 29 '11 at 19:44
  • @Billy: There is no polymorphic type here that I can see...? – Samaursa Jun 29 '11 at 19:51
  • I see no `m_x` in your `StructBase`. – Xeo Jun 29 '11 at 19:52
  • @Xeo: sorry, missed it when I was renaming – Samaursa Jun 29 '11 at 19:55
  • @Samaursa: There's inheritance going on here -- that's polymorphic. You're not using polymorphic dispatch (e.g. virtual functions), but the sizes of `Struct1`, `Struct2`, and `Struct3` are all different. (So they cannot go into an array) That is, there cannot be one array with two different concrete types inside. – Billy ONeal Jun 29 '11 at 19:55
  • If you try to create an array of `StructBase` and assign `Struct1`, `Struct2` or `Struct3` to that array, you'll simply run into the slicing problem. – Billy ONeal Jun 29 '11 at 19:57
  • @Billy: I thought inheritance only resulted in a polymorphic type when a virtual function was present? As for the array, the `vector<>` is storing any of the following types: Struct1, Struct2 or Struct3. It is not storing pointers or at any point storing the base class. – Samaursa Jun 29 '11 at 19:57
  • @Samaursa: So the `vector` is not `vector`? – Billy ONeal Jun 29 '11 at 19:59
  • @Samaursa: Then it should be fine. It sounded to me like you were trying to do `std::vector vec; vec.push_back(Struct1());`. – Billy ONeal Jun 29 '11 at 20:00
  • What happens when you replace myVec.push_back(Vector2(i, j)); with { myVec.push_back(Struct3()); myVec.back().SetPos(Vector2(i, j); }? Will removing constructors from Struct3 make any difference in the latter case? Is Vector you use std::vector or your own class? If it is the latter then perhaps there is something wrong with Vector template? – Tomek Jun 29 '11 at 21:00

0 Answers0