1

私はこの単純なプログラムを持っています。このプログラムを実行すると、セグメンテーション違反が発生し、どこに間違いがあるのか​​わかりません。どんな助けも歓迎します(Di> = 27のセグメンテーション違反)。重要なのは、機能をすぐに削除すると、セグメンテーション違反が消えることです。または、関数をvoid関数に変換するとき。削除演算子を使用しないため、リークメモリがあることはわかっています。リークメモリが発生しますが、セグメンテーション違反の原因にはなりません(このリークメモリはセグメンテーション違反を引き起こす可能性が非常に高いです)。簡単にするために、削除演算子は使用しませんでした。

 #include <iostream>
    #include<complex>
    using namespace std;
    const int Di=27;
    typedef struct {
         complex<double> Matrix[Di][Di][Di][Di];

        } O;

    O initializing(int );

    int main()
    {
    O * Operator=new O[1];
    int p;
    int n;
    Operator[0]=initializing(n);
    cout<<"hi";
    return 0;

    }



O initializing(int  point)
{
int i,j,m,n;
O *Operator=new O[1];
for(i=0;i<Di-1;i++)
    for(j=0;j<Di-1;j++)
        for(n=0;n<Di-1;n++)
            for(m=0;m<Di-1;m++)
            Operator[0].Matrix[i][j][m][n]=2;

            cout<<Operator[0].Matrix[Di-1][Di-1][Di-1][Di-1];
return Operator[0];


}
4

2 に答える 2

3

値で大きな配列を持つ構造体を返していますが、スタックに収まりません。ポインタで構造体を返し、呼び出し元でそのポインタを逆参照します。メモリリークを回避するのにも役立ちます。

O* initializing(int );

int main()
{
    O * Operator=new O[1];
    int p;
    int n;
    O *tmp = initializing(n);
    Operator[0] = *tmp;
    delete[] tmp;
    cout<<"hi";
    return 0;
 }
于 2012-07-21T13:48:33.860 に答える
2

問題は、オブジェクトを値で返すときに、一時オブジェクトがスタックに作成される可能性があることだと思います。を使用Di=27すると、各オブジェクトのサイズは数メガバイトになり、スタックがオーバーフローする可能性があります。

また、既存のオブジェクトをコピーするために新しいオブジェクトを初期化することにより、必要なメモリの少なくとも2倍のメモリを割り当て(およびリーク)します。

より良いオプションは、参照によって関数に初期化するオブジェクトを渡すことです。

void initialise(O & o, int point) {
    for (/*blah blah*/)
        o.Matrix[i][j][m][n]=2;
}

または構造体にコンストラクターを与えるには:

struct O {
    explicit O(int point) {
        for (/*blah blah*/)
            Matrix[i][j][m][n]=2;
    }

    complex<double> Matrix[Di][Di][Di][Di];
};

newいずれの場合も、 ;で割り当てたものはすべて削除することを忘れないでください。または、さらに良いことに、スマートポインタを使用してそれを実行します。

于 2012-07-21T13:58:37.903 に答える