4

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 を使用していません。0 はまだ有効な値であるため、文字列を作成して '\0' を追加しても意味がありません。

しかし、興味深い部分として、次のコードで swap 関数をテストしました。

#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 配列の作成、文字列、および配列の長さの一般的な計算ミスに関連しています。そして、コードに示されているように、私は常に配列の長さを他の関数に運びます。

私がしなければならないことを行うためのより良いコードがあると確信していますが、これは単独で必要なプロジェクトであるため、配列で何が間違っているかを確認するためだけに、より良い機能を探しているわけではありません.

4

1 に答える 1

8

コードが array の範囲外のインデックスに書き込むと、メモリが破損しますtemp。また、ヒープが破損すると、あらゆることが発生する可能性があります (delete[]通話中のクラッシュなど)。

配列にはアイテムtempが含まれていますが、二重ループ内では配列(size-1)*(size-1)として扱われます: (「最初のインデックス」に を乗算するため)。size*(size-1)temp[(i-1)*size + j-1] = ...size

temp[(i-1)*temp_size + j-1]に置き換えると問題が解決すると思います。

于 2013-06-08T12:04:00.707 に答える