0

私は2つの簡単なクラスを持っています。A クラスに空のデストラクタがある場合 (空の ~A(){};) 、すべて問題ありません。配列を解放する行を追加すると、プログラムでセグメンテーション違反が発生します。

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

class A
{
    private :

        int n;
        int m;
        int **array;

    public :

        A();
        A(int nn, int mm);
        A(const A& a);
        A& operator=(A a);
        int getAt(int i, int j);
        int getN(){return n;}
        int getM(){return m;}
        ~A();
};

A::A()
{
    n = 0;
    m = 0;
    array = NULL;
}

A::A(int nn, int mm)
{
    n = nn;
    m = mm;

    array = new int*[n];
    for(int i = 0; i <n; i++)
        array[i] = new int[m];

    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            array[i][j] = rand()%2;
}

A::A(const A& a)
{
    for(int i=0; i <n; i++)
        delete[] array[i];
    delete [] array;
    array = NULL;

    n = a.n;
    m = a.m;

    array = new int*[n];
    for(int i = 0; i <n; i++)
        array[i] = new int[m];

    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            array[i][j] = a.array[i][j];
}

A& A::operator=(A a)
{
    for(int i=0; i <n; i++)
        delete[] array[i];
    delete [] array;
    array = NULL;

    n = a.n;
    m = a.m;

    array = new int*[n];
    for(int i = 0; i <n; i++)
        array[i] = new int[m];

    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            array[i][j] = a.array[i][j];

    return *this;
}

int A::getAt(int i, int j)
{
    return array[i][j];
}

A::~A()
{
    for(int i=0; i <n; i++)
        delete[] array[i];
    delete [] array;
    array = NULL;
}

class B
{
    private :

            A a;

    public :

            B(){}
            B(A aa);
            void setA(A aa);
            void showA();
};

B::B(A aa)
{
    a = aa;
}

void B::setA(A aa)
{
    a = aa;
}

void B::showA()
{
    int n = a.getN();
    int m = a.getM();

    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++)
            cout << a.getAt(i,j) << " ";
        cout << "\n";
    }
    cout << "\n";
}

int main()
{
    A a(3, 4);
    B b(a);

    b.showA();

    return 0;
}

これを修正する方法は?そして、なぜそれが起こったのですか?

解決済み:

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

class A
{
    private :

        int n;
        int m;
        int **array;

    public :

        A();
        A(int nn, int mm);
        A(const A& a);
        A& operator=(const A& a);
        int getAt(int i, int j);
        int getN(){return n;}
        int getM(){return m;}
        ~A();
};

A::A()
{
    n = 0;
    m = 0;
    array = NULL;
}

A::A(int nn, int mm)
{
    n = nn;
    m = mm;

    array = new int*[n];
    for(int i = 0; i <n; i++)
        array[i] = new int[m];

    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            array[i][j] = rand()%2;
}

A::A(const A& a)
{
    n = a.n;
    m = a.m;

    array = new int*[n];
    for(int i = 0; i <n; i++)
        array[i] = new int[m];

    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            array[i][j] = a.array[i][j];
}

A& A::operator=(const A& a)
{
    for(int i=0; i <n; i++)
        delete[] array[i];
    delete [] array;
    array = NULL;

    n = a.n;
    m = a.m;

    array = new int*[n];
    for(int i = 0; i <n; i++)
        array[i] = new int[m];

    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            array[i][j] = a.array[i][j];

    return *this;
}

int A::getAt(int i, int j)
{
    return array[i][j];
}

A::~A()
{
    for(int i=0; i <n; i++)
        delete[] array[i];
    delete [] array;
    array = NULL;
}

class B
{
    private :

            A a;

    public :

            B(){}
            B(A aa);
            void setA(A aa);
            void showA();
};

B::B(A aa)
{
    a = aa;
}

void B::setA(A aa)
{
    a = aa;
}

void B::showA()
{
    int n = a.getN();
    int m = a.getM();

    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++)
            cout << a.getAt(i,j) << " ";
        cout << "\n";
    }
    cout << "\n";
}

int main()
{
    A a(3, 4);
    B b(a);

    b.showA();

    return 0;
}
4

2 に答える 2

2

コピー コンストラクターは、まず古い配列をn新しい配列で上書きし、次に古い配列の要素nを削除しようとします。nしかし、配列のサイズが異なる場合はどうなるでしょうか? ループn に上書きします。

または、さらに良いことに、この恐ろしいポインターの怪物を取り除き、std::vector代わりに使用します。

于 2013-05-10T09:34:35.317 に答える