2016-05-18 1 views
0

私はテンプレートを使用し、サイズを持つ単純な配列クラスを持っています。私はそれが満員のときはいつでもサイズを変更したいが、私のプログラムはクラッシュする。 コードは次のようである:。C++配列サイズ変更のクラッシュ

template<class T> 
class Buffer:public File_ptr 
{ 

    unsigned int siz; 
    T *data; 


public: 

    ///konstruktor(size,filename,openmode) 
    Buffer(unsigned int s=50,const char* n, const char* m):File_ptr(n,m),siz(s) 
    { 
     data= new T[siz]; 
     for(unsigned int i=0; i<siz; ++i) 
     { 
      data[i]=0; 
     }; 
    }; 

    ///destruktor 
    ~Buffer() 
    { 
     delete[] data; 
    } 

    ///operator[] 
    T& operator[](unsigned int i) 
    { 
     if(i>siz) 
     { 
      unsigned int newsize=siz*2; 
      T* tmp=new T[newsize]; 
      for(unsigned int j = 0; j < siz; j++) 
      { 
       tmp[j] = data[j]; 
      } 
      siz=newsize; 
      delete[] data; 
      data=tmp; 
      delete[] tmp; 
     }; 
     return data[i]; 
    } 

}; 

エラーがオペレータ[](少なくとも私は思う)に付属しています。 メインプログラムは、このようなものです:

int main() 
{ 
    Buffer<int> k(20,"k.txt","w"); 
    Buffer<char*> s(20,"s.txt","w"); 
    k.printfile("HEY"); 
    s.printfile(5); 
    for(unsigned int i=0;i<23;i++){ 
    s[i]="Hey"; 
    cout << s[i] << endl; 
    } 


return 0; 
} 

すべてのヘルプは素晴らしいことです! :) ありがとう!

答えて

0

メモリを2度削除しているため、セグメンテーションフォルトが発生しています。ここで

data=tmp; 
delete[] tmp; 

、あなたはtmpdataメモリ位置を割り当てます。これまでのところとても良い、datatmpは同じメモリ領域を指しています。しかし今あなたはdelete[] temp;なので、メモリ領域は削除されます。しかし、dataもそれを指しているので、dataもポインタ(tmpなど)として使用することはもはや有効ではありません。

次に、return data[i];で、そのメモリにアクセスしようとしていますが、削除しました。したがって、セグメンテーション違反が発生します。

あなたがあるため、その後dataポイントの有効なメモリ位置に、ないdelete[] tmp;によってこの問題を解決することができ、すべてがあなたはまだoperator[]tmpが参照するあなたの新鮮なアレイを削除:)

+0

ありがとうございました!出来た! :)) –

0

良いです。これはdataで参照される新しい配列なので、必然的に問題に遭遇します。

0

あなたにはいくつか問題があります。最初の問題は、tmpが指し示すメモリを削除して、dataが現在指しているものであることです。これは、次に配列が大きくなると、定義されていない動作である削除されたポインタにアクセスしていることを意味します。

第二の問題は、if(i>siz)チェックがiは、配列の最後を過ぎていますがinewsize以上であるかを確認したことがないということです。 newsizesiz * 2iの最大値に設定する必要があります。また、演算子[]がコンテナを拡張するのは直感的ではありません。コンテナより大きなサイズの[]を呼び出すと、配列のサイズを変更する代わりにエラーになります。

関連する問題