3

配列クラスの演算子<<>>!====および[]をオーバーロードしようとしています。コンパイルエラーは表示されませんが、実行時にアプリがクラッシュします。何が間違っている可能性がありますか?IDEはdevc++を使用しました

これがarray.hです

#ifndef ARRAY_H
#define ARRAY_H

#include <iostream>
using namespace std;

class Array{
  friend ostream & operator << ( ostream &, const Array & );
  friend istream & operator >> ( istream &, Array &);
  private:
         int size;
         int * ptr;
  public:
         Array ( int = 10 );
         Array ( const Array & ); //copy constructor
         ~Array ();
         const Array &operator=( const Array & ); 
         bool operator == ( const Array & ) const; 
         bool operator != ( const Array & ) const;
         const int operator [] (int) const; 
         int getSize() const;            
};

#endif

そして今array.cpp

#include <iostream>
using namespace std;
#include "array.h"

Array::Array (int sze ){ //default constructor edited
         size = (sze > 0 ? sze : 10);
         ptr = new int [ size ];
         for (int i = 0;  i < size; i++)
             ptr[ i ] = 0; //initial values
}
Array::Array (const Array & arr ): size(arr.size){
         ptr = new int [size];
         for ( int i = 0; i< size; i++)
             ptr [ i ] = arr.ptr [ i ];
}
Array::~Array(){
         delete [] ptr;
}
const Array &Array :: operator= ( const Array & right){//IMPO
         if(&right != this){ //edited self assignment test
                   if(size != right.size){//diff sized arrays
                           delete [] ptr; //reclaim space
                           size = right.size; 
                           ptr = new int [ size ]; //space created
                   }
         }
         for(int i=0; i<size; i++)
                 ptr[ i ] = right.ptr[ i ];
         return *this;     //enables cascading a=b=c       
}
bool Array::operator == ( const Array & right) const{
         if ( size != right.size )
            return false;
         for ( int i =0; i < size; i++ ){
             if ( ptr [ i ] != right.ptr[ i ] )
                return false;
         }
         return true;
 }
bool Array::operator != ( const Array & right ) const{ //edited
         return ! (*this == right);
}
const int Array::operator [] (int subscript) const{
         if(subscript >=0 && subscript < size)
            return ptr[ subscript ];      
}
int Array::getSize() const{ return size; }  
//friend functions not in .h
ostream & operator << ( ostream & output, const Array & array){
         for (int i = 0; i < array.size; i++)
             output << array.ptr[i] ; 
}
istream & operator >> ( istream & input, Array & array){
         for (int i = 0; i < array.size; i++)
             input >> array.ptr[i];
}

今main.cpp

#include <cstdlib>
#include <iostream>
#include "array.h" // " " not <>
using namespace std;

int main(int argc, char *argv[])
{
Array a1(7),a2 (-1),a4; //changed a2
cout<<"Input "<<a1.getSize()<<" integers for Array object a1 and "<<a2.getSize()<<" integers for Array objecta2\n";
cin>>a1>>a2;
cout<<"a1 and a2 are\n";
cout<<a1<<endl<<a2;
cout<<"a1!=a2 : "<<(a1!=a2)<<endl;
cout<<"a1 ==a2: "<<(a1==a2)<<endl;
cout<<"Printing a1[5] : "<<a1[5]<<endl;
Array a3(a1); 
a4 = a3;

system("PAUSE");
return EXIT_SUCCESS;
}
4

3 に答える 3

6

ptrコンストラクターでメモリを予約する必要があります。

Array::Array (int size ){ //default constructor
         size = (size > 0 ? size : 10);
         ptr = new int [size]; // ADD THIS LINE
         for (int i = 0;  i < size; i++)
             ptr[ i ] = 0; //initial values
}

クラッシュの直接の原因ではないが、注目に値するコードには他にもいくつかの問題があります。

  1. Array::operator !=それ自体の観点から定義されます。に似ている必要がありますoperator==。または、で再利用できます。

    if( *this == right )
        return false;
    return true;
    
  2. Array::operator []インデックスが範囲外の場合は、おそらく例外をスローする必要があります。現在、ガベージメモリを返すだけです。

  3. メンバーではなく、パラメーターArray::Array (int size )に割り当てる割り当ての内部。size最初の行を次のように変更します。

     this->size = (size > 0 ? size : 10);
    
  4. operator<<operator>>をそれぞれ返す必要がoutputありinputます。

    ostream & operator << ( ostream & output, const Array & array){
       for (int i = 0; i < array.size; i++)
           output << array.ptr[i] ; 
       return output;
    }
    
于 2012-10-26T19:58:21.150 に答える
1

また、at行の実装でエラーが発生しましたoperator !=if ( *this != right )-再帰的定義なので、スタックオーバーフロー。

于 2012-10-26T20:10:48.907 に答える
1

デフォルトのコンストラクターに2つのエラーがあります。

1)メモリを割り当てずptrに初期化しようとすると、これは確かにエラーであり、未定義の動作を引き起こします。したがって、無効な値がptrあると、セグメンテーション違反が発生したり、さらに悪いことに、一部の値が上書きされたりする可能性があります。内部変数!

2)デフォルトコンストラクタの変数の名前は、クラスのメンバーではなくsize = (size > 0 ? size : 10);ローカル変数のサイズと変更値です。そのため、メンバーは初期化されないままであり、その使用は違法であり、セグメンテーション違反などの例外が発生する可能性があります。たとえば、それは確かにアレイの終わりをはるかに超えている可能性があります。sizesizesizesize7476327436

また、エラーが1つあることに加えて、これは比較に使用されますoperator !=if ( *this != right )これoperator !=はすべての場合に再帰関数であり、スタックオーバーフロー例外が発生するため、正確なポインタを確認する場合は、if ( this != right )代わりにを使用してください。それ。

初めてコードを確認したときは完全にはチェックしていませんが、コードに他のエラーがあり、コンパイル方法もわかりません。複数の場所で、関数の戻り値を提供していません。プログラミングエラーの修正に役立つコンパイラの警告が存在することを決して無視しないでください。

const int Array::operator [] (int subscript) const{
    if(subscript >=0 && subscript < size)
        return ptr[ subscript ];
    // If not what should I do?? add a return value here, this is a warning
    // since compiler think somehow you know that your code never reach here
    // but do you really know??
    return 0;
}
ostream & operator << ( ostream & output, const Array & array){
    for (int i = 0; i < array.size; i++)
        output << array.ptr[i] ;
    // You say that your function return an ostream& but where is it??
    // this is an error so compiler have nothing to return instead of you!
    // And if your compiler does not generate an error possibly it return 
    // junk value that will cause an error!!
    return output;
}
istream & operator >> ( istream & input, Array & array){
    for (int i = 0; i < array.size; i++)
        input >> array.ptr[i];
    // again you forget to return an istream& and again this is an error
    return input;
}

しかし、コードにエラーは見られず、エラーなしで実行されるはずです。

于 2012-10-26T20:25:22.340 に答える