std::vector of vectors deallocates its shared_ptr content (incorrect usage of stack solid objects?)

barney

Vector of vectors of shared_ptr deallocates its Piece instances. I created it in my Board class like this:

std::vector < std::vector < std::shared_ptr <Piece> > > board; 

But it deallocates each time the inner cycle leaves the scope:

Board::board with capacity 10 size: 10
Piece born 0x7faedbc1dc78
Row 0 Column 0 piece0x7faedbc1dc78
Piece born 0x7faede303fd8
Row 1 Column 0 piece0x7faede303fd8
Piece born 0x7faede30d2a8
Row 2 Column 0 piece0x7faede30d2a8
Piece born 0x7faede30d248
Row 3 Column 0 piece0x7faede30d248
Piece born 0x7faede30d348
Row 4 Column 0 piece0x7faede30d348
Piece born 0x7faede30d368
Row 5 Column 0 piece0x7faede30d368
Piece born 0x7faede30d4c8
Row 6 Column 0 piece0x7faede30d4c8
Piece born 0x7faede30d4e8
Row 7 Column 0 piece0x7faede30d4e8
Piece born 0x7faede30d508
Row 8 Column 0 piece0x7faede30d508
Piece born 0x7faede30d528
Row 9 Column 0 piece0x7faede30d528
Piece death 0x7faede30d528
Piece death 0x7faede30d508
Piece death 0x7faede30d4e8
Piece death 0x7faede30d4c8
Piece death 0x7faede30d368
Piece death 0x7faede30d348
Piece death 0x7faede30d248
Piece death 0x7faede30d2a8
Piece death 0x7faede303fd8
Piece death 0x7faedbc1dc78
Piece born 0x7faede303fd8
Row 0 Column 1 piece0x7faede303fd8
Piece born 0x7faede30d2a8
Row 1 Column 1 piece0x7faede30d2a8
Piece born 0x7faede30d248
Row 2 Column 1 piece0x7faede30d248
Piece born 0x7faedbe7db98
Row 3 Column 1 piece0x7faedbe7db98
Piece born 0x7faedbe8f6a8
Row 4 Column 1 piece0x7faedbe8f6a8
Piece born 0x7faedbe8f868
Row 5 Column 1 piece0x7faedbe8f868
Piece born 0x7faedbe8f888
Row 6 Column 1 piece0x7faedbe8f888
Piece born 0x7faedbe8f8a8
Row 7 Column 1 piece0x7faedbe8f8a8
Piece born 0x7faedbe8f8c8
Row 8 Column 1 piece0x7faedbe8f8c8
Piece born 0x7faedbe8f8e8
Row 9 Column 1 piece0x7faedbe8f8e8
Piece death 0x7faedbe8f8e8
Piece death 0x7faedbe8f8c8
Piece death 0x7faedbe8f8a8
Piece death 0x7faedbe8f888
Piece death 0x7faedbe8f868
Piece death 0x7faedbe8f6a8
Piece death 0x7faedbe7db98
Piece death 0x7faede30d248
Piece death 0x7faede30d2a8
Piece death 0x7faede303fd8
Piece born 0x7faedbe7db98
Row 0 Column 2 piece0x7faedbe7db98 ...

Heres the Board class code:

#include "Board.h"
#include <iostream>

using namespace std;

Board::Board(int width_, int height_) : width(width_), height(height_), board(height)
{
    cout << "Board::board with capacity " << board.capacity() << " size: " << board.size() << endl;
//    board = vector< vector < shared_ptr < Piece >>> (height) ;

    for (int i=0; i<height; i++)
    {
        vector < shared_ptr < Piece > > row(width);
        board[i] = row;

        for (int j=0;j<width;j++) {
            shared_ptr< Piece > piece = make_shared<Piece>();
            row[j] = piece;
            cout << "Row " << j << " Column " << i << " piece" << &*piece << endl;
        }
    }
}

Relevant Piece code (basically it just squacks)

class Piece {
public:
    Piece() { std::cout << "Piece born " << this << std::endl;}
    ~Piece() { std::cout << "Piece death " << this << std::endl;}
    Piece(const Piece &rhs) {
        std::cout << "Piece copy " << this << " from " << &rhs << std::endl;
    }
    Piece & operator=(const Piece & rhs) {
        std::cout << "Piece assigned " << this << " from " << &rhs << std::endl;
        return *this;
    }
};

No copy or assign operators are invoked. So I believe its NOT due to vector self-reallocation because I pre-allocated outermost vector in Board's constructor (as well as local vector allocated to "width" in inner cycle)

Angew is no longer proud of SO
board[i] = row;

This copies the contents of the row vector at the time of the assignment into board[i]. Then, you proceed to fill the local row vector, but do nothing more with it.

Move the assignment until after loop:

for (int i=0; i<height; i++)
{
    vector < shared_ptr < Piece > > row(width);

    for (int j=0;j<width;j++) {
        shared_ptr< Piece > piece = make_shared<Piece>();
        row[j] = piece;
        cout << "Row " << j << " Column " << i << " piece" << &*piece << endl;
    }
    board[i] = std::move(row);
}

Alternatively, to get rid of the assignment altogether, you could introduce row as simply an alias:

for (int i=0; i<height; i++)
{
    auto &row = board[i];
    row.resize(width);

    for (int j=0;j<width;j++) {
        shared_ptr< Piece > piece = make_shared<Piece>();
        row[j] = piece;
        cout << "Row " << j << " Column " << i << " piece" << &*piece << endl;
    }
}

If you want to streamline the code even more, you can do this (I would even say it's clearer):

for (int i=0; i<height; i++)
{
    auto &row = board[i];

    for (int j=0;j<width;j++) {
        row.emplace_back(make_shared<Piece>());
        cout << "Row " << j << " Column " << i << " piece" << row.back().get() << endl;
    }
}

Notice that std::shared_ptr::get() returns the raw pointer, and I personally find it preferable to &*.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

boost::shared_ptr<std::vector<something>> usage of operator[]

From Dev

Specifying a Deleter for std::shared_ptr that works on all objects of a particular type or its derived types

From Dev

Replacing shared_ptr elements in std::vector

From Dev

Inserting std::shared_ptr with lambda into a vector

From Dev

Replacing shared_ptr elements in std::vector

From Dev

Vector iterator not dereferencable with std::shared_ptr<>

From Dev

Split vector into several vectors depending on its content

From Dev

Thread synchronization between data pointed by vectors of std::shared_ptr

From Dev

Initializing boost::shared_ptr<std::vector<T>> with boost::shared_ptr<std::list<T>>

From Dev

Is using std::vector< std::shared_ptr<const T> > an antipattern?

From Dev

Transfer ownership from std::vector to std::shared_ptr

From Dev

Is using std::vector< std::shared_ptr<const T> > an antipattern?

From Dev

Transfer ownership from std::vector to std::shared_ptr

From Dev

Usage of vector::emplace_back with shared_ptr

From Dev

When does std::shared_ptr release its object?

From Dev

How to erase a certain element from a shared_ptr to a vector of objects?

From Dev

How does std::vector destruct its objects?

From Dev

std::shared_ptr in QList does not delete content on deletion

From Dev

Maximum number of std::shared_ptr managed objects per process

From Dev

std::shared_ptr causing issues while copying objects

From Dev

Managing objective-C objects with c++ std::unique_ptr<> or std::shared_ptr<>

From Dev

Managing objective-C objects with c++ std::unique_ptr<> or std::shared_ptr<>

From Dev

C++ OpenMP object counter incorrect counts with std::vector of objects

From Dev

How to copy std::vector<boost::shared_ptr<T>> to std::list<T>

From Dev

How to copy std::vector<boost::shared_ptr<T>> to std::list<T>

From Dev

Class template with variadic constructor; storing parameters into std::vector< std::shared_ptr<> >

From Dev

Cast 'this' to std::shared_ptr

From Dev

std::shared_ptr and Inheritance

From Dev

std::function and shared_ptr

Related Related

  1. 1

    boost::shared_ptr<std::vector<something>> usage of operator[]

  2. 2

    Specifying a Deleter for std::shared_ptr that works on all objects of a particular type or its derived types

  3. 3

    Replacing shared_ptr elements in std::vector

  4. 4

    Inserting std::shared_ptr with lambda into a vector

  5. 5

    Replacing shared_ptr elements in std::vector

  6. 6

    Vector iterator not dereferencable with std::shared_ptr<>

  7. 7

    Split vector into several vectors depending on its content

  8. 8

    Thread synchronization between data pointed by vectors of std::shared_ptr

  9. 9

    Initializing boost::shared_ptr<std::vector<T>> with boost::shared_ptr<std::list<T>>

  10. 10

    Is using std::vector< std::shared_ptr<const T> > an antipattern?

  11. 11

    Transfer ownership from std::vector to std::shared_ptr

  12. 12

    Is using std::vector< std::shared_ptr<const T> > an antipattern?

  13. 13

    Transfer ownership from std::vector to std::shared_ptr

  14. 14

    Usage of vector::emplace_back with shared_ptr

  15. 15

    When does std::shared_ptr release its object?

  16. 16

    How to erase a certain element from a shared_ptr to a vector of objects?

  17. 17

    How does std::vector destruct its objects?

  18. 18

    std::shared_ptr in QList does not delete content on deletion

  19. 19

    Maximum number of std::shared_ptr managed objects per process

  20. 20

    std::shared_ptr causing issues while copying objects

  21. 21

    Managing objective-C objects with c++ std::unique_ptr<> or std::shared_ptr<>

  22. 22

    Managing objective-C objects with c++ std::unique_ptr<> or std::shared_ptr<>

  23. 23

    C++ OpenMP object counter incorrect counts with std::vector of objects

  24. 24

    How to copy std::vector<boost::shared_ptr<T>> to std::list<T>

  25. 25

    How to copy std::vector<boost::shared_ptr<T>> to std::list<T>

  26. 26

    Class template with variadic constructor; storing parameters into std::vector< std::shared_ptr<> >

  27. 27

    Cast 'this' to std::shared_ptr

  28. 28

    std::shared_ptr and Inheritance

  29. 29

    std::function and shared_ptr

HotTag

Archive