gpt4 book ai didi

c++ - std::vector of vectors 释放其 shared_ptr 内容(堆栈实体对象的使用不正确?)

转载 作者:行者123 更新时间:2023-11-30 02:36:39 24 4
gpt4 key购买 nike

shared_ptr 的 vector 的 vector 释放其 Piece 实例。我在 Board 类中创建它是这样的:

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

但每次内部循环离开范围时它都会释放:

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 ...

这是 Board 类代码:

#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;
}
}
}

相关Piece代码(基本上就是乱码)

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;
}
};

没有调用复制或赋值运算符。所以我相信这不是由于 vector 的 self 重新分配,因为我在 Board 的构造函数中预先分配了最外层的 vector (以及在内部循环中分配给“宽度”的局部 vector )

最佳答案

board[i] = row;

这会将 row vector 的内容在赋值时复制到 board[i] 中。然后,您继续填充本地 row vector ,但不再对其进行任何操作。

将赋值移动到循环之后:

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);
}

或者,要完全摆脱分配,您可以引入 row 作为简单的别名:

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;
}
}

如果你想更精简代码,你可以这样做(我什至会说它更清晰):

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;
}
}

请注意 std::shared_ptr::get() 返回原始指针,我个人认为它比 &* 更可取。

关于c++ - std::vector of vectors 释放其 shared_ptr 内容(堆栈实体对象的使用不正确?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32474162/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com