调用delete[]时,某些东西导致堆损坏,但我已正确设置了数组的维度

Something is causing heap corruption when calling delete[] but I have dimensions of array set up correctly

本文关键字:设置 数组 损坏 delete 调用      更新时间:2023-10-16

我发现delete[]上的堆损坏错误是由于在某个地方写东西时没有分配任何东西(根据以下帖子:First post,Second post(引起的,问题是即使在这种情况下尝试找到问题,我仍然找不到。

我要创建一个简单的数据库表,作为函数的参数,我得到一行必须与列数据类型相对应的数据。

所以基本上我在其他数组(2d数组(上创建了一个指针数组,这样每个数组都是行。

这是表类的声明:

class DLL_SPEC Table {
public:
void insert(Object** row);
void remove(int rowid);
Iterator* select();
void commit();
void close();
int getRowCount() const;
FieldObject** getFields() const;
int getFieldCount() const;
void setName(std::string name) { _nameOfTable = name; };
void setNumberOfFields(int numberOfFields) { _numberOfFields = numberOfFields; }
void setNumberOfRows(int numberOfRows) { _numberOfRows = numberOfRows; }
void setFields(FieldObject** fields) { _fields = fields; }
Iterator* select(Condition* condition) { throw 0; }
int findRowId(Condition* condition) { throw 0; }
void update(Condition* condition, std::function<void(Object**)> callback) { throw 0; }
private:
std::string _nameOfTable;
int _numberOfFields;
int _numberOfRows;
FieldObject** _fields;
Object*** _rowValues;
};

这是导致delete[]tmpArray处堆损坏错误的插入方法。

void Table::insert(Object** row)
{
Object*** tmpArray = new Object**[_numberOfRows + 1];
Object** checkedRow = new Object*[_numberOfFields];
// extend the array by 1 new row
for (size_t i = 0; i < _numberOfRows; i++)
{
tmpArray[i] = new Object*[_numberOfFields];
}
for (size_t i = 0; i < _numberOfRows; i++)
{
for (size_t j = 0; j < _numberOfFields; j++)
{
tmpArray[i][j] = _rowValues[i][j];
}
}
// check if the new row contains correct values for table
for (size_t i = 0; i < _numberOfFields; i++)
{
if (StringObject* v = dynamic_cast<StringObject*>(row[i]))
{
if (v->isType(_fields[i]->getType()))
{
checkedRow[i] = v;
}
continue;
}
if (IntObject* v = dynamic_cast<IntObject*>(row[i]))
{
if (v->isType(_fields[i]->getType()))
{
checkedRow[i] = v;
}
continue;
}
if (DoubleObject* v = dynamic_cast<DoubleObject*>(row[i]))
{
if (v->isType(_fields[i]->getType()))
{
checkedRow[i] = v;
}
continue;
}
throw std::invalid_argument("The fields of this table don't match with the data you want to enter.");
}
tmpArray[_numberOfRows + 1] = checkedRow;
_numberOfRows++;
_rowValues = tmpArray;
delete[] tmpArray;
delete[] checkedRow;
}

使用为tmpArray分配一些空间

Object*** tmpArray = new Object**[_numberOfRows + 1];

在函数结束时,您写入

tmpArray[_numberOfRows + 1] = checkedRow;

其写入超过所分配空间的末尾(下标从0运行到_numberOfRows(,导致未定义的行为。

此外,即使它没有在这里崩溃,它稍后也会崩溃,因为您将tmpArray分配给_rowValues,然后删除tmpArray,使_rowValues处于悬空状态,从而在取消引用该指针时导致将来出现问题。