【问题标题】:Incorrect checksum for freed object - error when printing已释放对象的校验和不正确 - 打印时出错
【发布时间】:2017-04-15 07:09:59
【问题描述】:

我已经创建了一个应该创建对称 toeplitz 矩阵的类 (see here)。类的实现如下所示

class toeplitz{
private:
    int size;
    double* matrix;
public:
    toeplitz(const double* array, const int dim){
         size = dim;
         matrix = new double(size*size);
         for(int i = 0; i < size; i++){
             for (int j = 0; j < size; j++){
                 int index = std::abs(i - j);
                 matrix[i*size + j] = array[index];
             }
         }
    }

    ~toeplitz(){
        delete[] matrix;
    }

    void print() const{
        //loop over rows
        for (int i = 0; i < size; i++){
            //loop over colums
            for (int j = 0; j < size; j++){
                double out = matrix[i*size + j];
                std::cout << std::setw(4) << out;
            }
        //start new line for each row
        std::cout << "\n";
        }
    }

};

我看不出这有什么问题,但是当我尝试在一个简单的测试函数中使用它时,我得到了 malloc 错误。我的主要功能是

int main(){
    double array[] = {0,1,1,2};
    int len = sizeof(array)/sizeof(array[0]);
    std::cout<<"length of array " << len << std::endl;
    toeplitz tp = toeplitz(array, len);
    tp.print();
}

当我省略 tp.print() 行时它编译并运行,但是当我添加此行时出现错误

test_toeplitz(8747,0x7fffdbee63c0) malloc: *** error for object 0x7fb119402788: 
incorrect checksum for 
freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

我不知道为什么会这样。我已经在此处查看了有关此问题的其他问题,但我无法说出它们与我所做的事情有何关系。据我了解,这与双重释放内存或在释放内存后尝试修改内存有关,但我看不到我的代码在哪里执行此操作。任何对正在发生的事情的见解将不胜感激。

【问题讨论】:

  • 我应该补充一下,偶尔它实际上运行良好,有时它会给出错误“分段错误:11”
  • 对象可能在被释放后被修改。我会调查一下..
  • 我应该补充一下,偶尔它实际上运行正常,有时它会给出错误“分段错误:11”这是一个明确指示未定义的行为。
  • 这会给你带来麻烦:toeplitz tp = toeplitz(array, len); 你没有遵循 3/5 的规则你的班。结果,您将双重删除您的矩阵。
  • 我不知道 3/5 的规则到底是什么,你能解释一下或提供解释的链接吗?

标签: c++


【解决方案1】:

你偶然发现了经典:

matrix = new double(size*size);

当你想做的时候,它会分配一个双倍的价值size*size

matrix = new double[size*size];

分配一个适当大小的数组。所以你会得到未定义的行为。有时它工作有时不取决于内存配置。

由于您使用的是 C++,我建议您使用 std::vector&lt;double&gt; 或 Eigen 矩阵模板,并永远丢弃 C 数组(不再有内存泄漏,不再有分配失败,可能的边界检查,只有优点)

【讨论】:

  • 或者更好的向量(是的,我知道向量不会改变大小,但是嘿,它避免了手动内存管理!并且可能会抛出索引越界异常)
  • 使用向量并不能保证使用[] 运算符进行边界检查。您必须使用vector::at 来检查边界。但同意(并且在您发表评论时正在编辑我的答案)
  • 是的,我知道这不是保证,所以我说可能。我 认为 VS 的实现已经断言了 YMMV。 ;)(别担心你已经得到了我的upboat)
  • 我记得我受够了这一点,并从 vector 继承,以便在启用宏定义时向 [] 添加边界检查。
  • 不客气。我希望你能告诉你的老师,C 数组是邪恶的
猜你喜欢
  • 2015-03-08
  • 2011-08-04
  • 2010-09-18
  • 1970-01-01
  • 2017-07-17
  • 2013-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多