1

Problem is to create a std::vector data table (struct MegaTable, from the example below), where items (struct DataItem, from the example below) could have a pointer to the whole data array.

Here is my code:

#include <vector>

struct MegaDataItem;

struct DataItem 
{
     int            a_;
     char*          ch_;

     MegaDataItem*  ptr_;

     DataItem( int _a, char* _ch, MegaDataItem* ptr )
          : a_( _a )
          , ch_( _ch )
          , ptr_( ptr )
     {}
};
typedef std::vector< DataItem > DataTable;


struct MegaDataItem 
{
     int            b_;
     DataTable      data_;

     MegaDataItem( int _b )
          : b_( _b )
     {
          for ( int j = 15; j >= 10; j-- )
          {
               DataItem item( j, "", this );
               data_.push_back( item );
          }
     }
};
typedef std::vector< MegaDataItem > MegaTable;


int main( int argc, char** argv )
{
     MegaTable table;

     for ( int i = 0; i < 5; i++ )
     {
          MegaDataItem megaItem( i );
          table.push_back( megaItem );
     }
     return 0;
}

And debug snapshot from MSVS:

enter image description here

As you can see, ptr_ pointer everywhere equals to 0x0031fccc, but that is not correct! Pointer must consists with correct struct MegaDataItem data, where all struct DataItem's exists...

Thanks for the help!

PS. I know that this is not the hard question, but I can't get it, how to get this things work!


UPDATE (corrected solution): PS: thnks to jpalecek! :)

MegaDataItem( const MegaDataItem& other )
          : b_( other.b_ )
     {
          data_.clear();
          DataTable::const_iterator d_i( other.data_.begin() ), d_e( other.data_.end() );
          for ( ; d_i != d_e; ++d_i )
               data_.push_back( DataItem( (*d_i).a_, (*d_i).ch_, this ) );
     }

void operator=( const MegaDataItem& other )
     {
          b_ = other.b_;

          data_.clear();
          DataTable::const_iterator d_i( other.data_.begin() ), d_e( other.data_.end() );
          for ( ; d_i != d_e; ++d_i )
               data_.push_back( DataItem( (*d_i).a_, (*d_i).ch_, this ) );
     }

2 Answers 2

3

The problem is your MegaDataItem structure is not copyable and assignable (if you copy or assign the vector in MegaDataItem, the back pointers will point to the original MegaDataItem, which is incorrect). You have to amend that.

Particularly, you'll have to implement the copy-constructor and assignment operator. In these, you have to redirect the ptr_ pointers in DataItems to the new MegaDataItem.

Example implementation:

MegaDataItem(const MegaDataItem& other) : b_(other.b_) {
  // fill data
  for(DataItem& item : other.data_)
    data_.push_back(DataItem(item.a_, item.ch_, this));
}

operator=(const MegaDataItem& other) {
  b_=other.b_;
  data_.clear();
  for(DataItem& item : other.data_)
    data_.push_back(DataItem(item.a_, item.ch_, this));
}

BTW, depending on what ch_ in DataItem means, you may want to implement these in DataItem, too.

Sign up to request clarification or add additional context in comments.

2 Comments

Thnks for the reply! And how to do this? I mean, I know that I have to re implement copy-contructor & operator[], but how?
See edit. Note this is just an example, it could be implemented otherwise.
0

Eh, it seems to be working as intended. You're passing this to DataItem's constructor, so of course all the DataItems created by a MegaDataItem will share the same ptr_ value.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.