根据我对C ++约定的理解,我有:
class BlockRepresentation : public FPRepresentation
{
private:
class Block
{
public:
int id;
int fpDimensions;
int* position; // pointers in question
int* blockDimensions; // pointers in question
~Block();
};
std::vector<Block> all_blocks;
public:
BlockRepresentation( int count, int dimensions, int volumn[] );
void AddBlock( int id, int position[], int dimensions[] );
std::string ToGPL();
};
在AddBlock
中创建新块:
void BlockRepresentation::AddBlock( int id, int position[],
int dimensions[] )
{
Block newBlock;
newBlock.id = id;
newBlock.fpDimensions = fpDimensions;
newBlock.position = new int[fpDimensions]; // pointers in question
newBlock.blockDimensions = new int[fpDimensions]; // pointers in question
for (int i = 0; i < fpDimensions; ++i)
{
newBlock.position[i] = position[i];
newBlock.blockDimensions[i] = dimensions[i];
}
all_blocks.push_back( newBlock );
}
所以我有以下析构函数:
BlockRepresentation::Block::~Block()
{
delete[] position;
delete[] blockDimensions;
}
然后我得到:
rep_tests(11039,0x7fff71390000) malloc: *** error for object 0x7fe4fad00240: pointer being freed was not allocated
为什么我不能delete[]
这里的2个指针?
答案 0 :(得分:1)
正如评论中指出的那样,你违反了三条规则,违规行为非常明显:
{
Block newBlock;
// snip
all_blocks.push_back( newBlock );
}
当此函数返回时,newBlock
对象超出范围,其析构函数将删除所有new
ed数组。
但你push_back
()编辑了这个对象。这将对象的副本构造到向量中。因为Block
没有定义复制构造函数,所以默认的复制构造函数只是复制了new
ed数组的所有指针。
如果你以某种方式设法避免取消引用不再有效的指针,或者你在那段经历中幸存下来,那么你还没有进入森林。这是因为,当向量被破坏并且其Block
被破坏时,它们的析构函数将再一次尝试delete
相同的new
ed数组delete
d之前一次。
即时崩溃。
答案 1 :(得分:1)
您的Block
析构函数没有任何问题。它正在完成它的工作,即释放两个int *
成员变量所指向的内存。问题是析构函数被多次调用相同的指针值,这导致双重自由错误。
导致此问题的实体是std::vector<Block>
,因为std::vector
将复制您的Block
对象,而您的Block
对象无法安全复制。
由于Block
的成员变量是position
和blockDimensions
,因此缓解此问题的最简单方法是使用std::vector<int>
而不是{{1 },如this sample program所示。
但是,如果您真的想使用int *
,则需要实现用户定义的复制构造函数。此外,用户定义的赋值运算符将补充复制构造函数。这就是所谓的Rule of Three。
int *
查看实时样本here。
查看我们必须跳过的所有箍,以便 #include <algorithm>
//...
class Block
{
public:
int id;
int fpDimensions;
int *position;
int *blockDimensions;
Block() : position(nullptr), blockDimensions(nullptr),
id(0), fpDimensions(0) {}
~Block()
{
delete [] position;
delete [] blockDimensions;
}
Block(const Block& rhs) : id(rhs.id), fpDimensions(rhs.fpDimensions),
position(new int[rhs.fpDimensions]),
blockDimensions(new int[rhs.fpDimensions])
{
std::copy(rhs.position, rhs.position + fpDimensions, position);
std::copy(rhs.blockDimensions, rhs.blockDimensions + fpDimensions,
blockDimensions);
}
Block& operator=(const Block& rhs)
{
Block temp(rhs);
std::swap(temp.position, position);
std::swap(temp.blockDimensions, blockDimensions);
std::swap(temp.id, id);
std::swap(temp.fpDimensions, fpDimensions);
return *this;
}
};
类在Block
内使用时能够正常运行,而不是简单地使用std::vector
?