【问题标题】:Heap corruption on delete[]删除时的堆损坏[]
【发布时间】:2013-06-04 15:47:43
【问题描述】:

我在 delete[] 指令上遇到了堆损坏错误。项目是在 VC++ 2008 中进行的,它的要求(所以请不要专注于此)。整个构建过程运行正常,但在运行时出现错误:(prs_2013 是我的项目名称)

Windows 已在 prs_2013.exe 中触发断点。

这可能是由于堆损坏,这表明 prs_2013.exe 或其已加载的任何 DLL 中存在错误。

这也可能是由于用户在 prs_2013.exe 获得焦点时按 F12。

输出窗口可能有更多的诊断信息。

这是发生错误的代码,它只是整个项目的一小部分,但错误仅限于该区域:

// Function used for swapping row of matrix with new values 
void Main::swap(double* matrix, double* row, unsigned index, unsigned size){
    double temp = 0;
    for(unsigned i = 0; i < size; i++){
        temp = matrix[i*size + index];
        matrix[i*size + index] = row[i];
        row[i] = temp;
    }
}

// Function that do some calculations, not really relevant for this problem
    // but still used in code
double Main::determinat(double* matrix, unsigned size){
    double ud = 0, du = 0;
    for(unsigned  j = 0; j < size; j++){
        double ude = 1, due = 1;
        for(unsigned  i = 0; i < size; i++){
            ude *= matrix[i*size + (i+j)%size];
            due *= matrix[(size-i)*size + (i + j)%size];
        }
        ud += ude;
        du += due;
    }
    return ud - du;
}

// Function in which error occurs 
double* Main::get_x(double* matrix, unsigned size){
        // error checking
    if(size == 1){return NULL;}

    double *x = new double[size];  
    x[0] = 1;
    unsigned const temp_size = size-1;

    double *temp = new double[temp_size * temp_size];   // temporary matrica    

    double *x0_coef = new double[temp_size]; // variable on which error occures

    for(unsigned i = 0; i < temp_size; i++)
        x0_coef[i] = matrix[i*size + 0] / s[0];     // s is class member, init in constructor s[0] != 0

    for(unsigned i = 1; i < size; i++)
        for(unsigned j = 1; j < size; j++)
            if(i == j)
                temp[(i-1)*size + j-1] = (matrix[i*size + j] - 1) / s[i];
            else
                temp[(i-1)*size + j-1] =  matrix[i*size + j] / s[i];

    double deltaS = determinat(temp, temp_size);        // delta of system
    for(unsigned i = 0; i < temp_size; i++){    // delta of vars
        swap(temp, x0_coef, i, temp_size);
        x[i+1] = determinat(temp, temp_size) / deltaS;
        swap(temp, x0_coef, i, temp_size);
    }

    delete[] x0_coef;  // place where error occures
    delete[] temp;
    return x;
}

但如果我将delete[] x0_coef; 切换为delete[] temp;,也会发生同样的事情,温度会出现错误;

正如您在代码中看到的那样,我没有使用 char,即。制作 String 所以添加 '\0' 是没用的,因为 0 仍然是有效值。

但现在有趣的部分,我已经用这段代码测试了交换功能:

#include <iostream>
using namespace std;

void swap(double* a, double* b, unsigned size){
    double temp = 0;
    for(unsigned i=0; i < size; i++){
        temp = a[i];
        a[i] = b[i];
        b[i] = temp;
    }
}

void main(){
    double *a = new double[5],
                *b = new double[5];
    for(unsigned i=0; i < 5; i++){
        a[i] = i;
        b[i] = i*i;
    }

    swap(a, b, 5);

    for(unsigned i=0; i < 5; i++)
        std::cout << "a: " << a[i] << " b: " << b[i] << endl;

    delete[] a;
    delete[] b;

    system("PAUSE");

}

一切正常。

说实话,我已经不知所措了,我花了 2 到 3 天的时间试图找出我错过了什么。但大多数其他主题都与制作 char 数组、String 和数组长度的一般未命中计算有关。正如代码中所示,我总是将数组长度传递给其他函数。

我确信有更好的代码来做我必须做的事情,但这是单独需要的项目,所以我不是为了帮助我了解我在使用数组时做错了什么而寻找更好的功能。

【问题讨论】:

  • 当您使用原始指针 newdelete(或它们的对应数组)进行手动内存管理时,就会发生这种情况。我建议使用 RAII 包装器,例如 std::vector。 Boost 还有用于多维数组的类
  • 当使用原始指针进行不正确的内存管理时会发生这种情况。
  • 我知道我可以使用已经制作好的库,但这不是这个项目的要求。除了 我不能使用任何其他库。我真的不能告诉你,但我什至实现了链表和循环缓冲区。当我试图在两天内不睡觉地完成整个项目时,就会发生这种事情。

标签: c++ runtime-error delete-operator heap-corruption


【解决方案1】:

您的代码在写入数组temp 的越界索引时会损坏内存。而且当堆损坏时,任何事情都可能发生(例如delete[] 调用崩溃)。

您的temp 数组包含(size-1)*(size-1) 项,而它在双循环内被视为size*(size-1) 数组:temp[(i-1)*size + j-1] = ...(因为您将“第一个索引”乘以size)。

我想用temp[(i-1)*temp_size + j-1] 替换它会解决问题。

【讨论】:

  • 非常感谢。我已经失明地盯着我的显示器看了 10 个小时。从测试代码复制/粘贴时出错。
  • 想插话并说我在delete 上遇到了运行时错误,但没有任何错误消息。我花了一段时间才发现这是原因。我为一些数组分配了很少的内存并使用了超出范围的索引。
猜你喜欢
  • 2013-04-20
  • 2013-01-23
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 2013-04-15
相关资源
最近更新 更多