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

标签 c++ arrays heap-corruption

我发现 delete[] 上的堆损坏错误是由于在我没有分配任何东西的地方写的(根据这些帖子:First postSecond post),问题是即使在试图在这种情况下找到问题,我仍然无法找到它。

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

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

这是表类的声明:

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 悬空会在您取消引用该指针时导致 future 出现问题。

关于c++ - 调用 delete[] 时某些东西导致堆损坏,但我正确设置了数组的维度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58848089/

相关文章:

c++ - Linux交叉编译的Makefile

c++ - 为我的类(class)重载流运算符 << >> 的正确方法是什么?

c++ - 调用堆栈上大量对象的构造函数

c++ - 运行时类型检查

c++ - 如何正确删除多维 vector ?

c - 基于\0 终止的循环无法正常工作?

PHP 数组到 postgres 数组

c++ - 使用 cv::FlannBasedMatcher 和 std::vector 的堆损坏

c - 检测到堆损坏 - 使用字符串实现合并排序

c - 堆的以下代码损坏是什么?