2017-07-12 4 views
-2

配列クラス用の関数を含むテンプレートクラスを作成しようとしています。 int型、float型、double型で動作するようですが、文字列では機能しません。私は含まれており、名前空間stdを使用しています。配列のサイズを変更するためのテンプレート

文字列を使用しない限り、すべてがコンパイルされ、うまく動作します。この場合、サイズ変更機能でエラーが発生します。 (すべてがコンパイルされ、エラーはここでしか存在しないため)私は、次の関連するコードを持っている、ヘッダファイル内

template<typename T> 
void Array<T>::resize(int newSize) 
{ 
    T* newArray = new T[newSize]; 
    if (newSize >= mSize) 
    { 
     for (int i = 0; i < newSize; ++i) 
      newArray[i] = mData[i]; 
    } 
    else 
     for (int i = 0; i < mSize; ++i) 
      newArray[i] = mData[i]; 
    delete[] mData; 
    mData = new T[newSize]; 
    mSize = newSize; 
    for (int i = 0; i < newSize; ++i) 
     mData[i] = newArray[i]; 
    delete[] newArray; 
    newArray = 0; 
} 

は、事前にありがとうございます。新しいサイズが古いサイズよりも大きい場合、あなたは古い配列からnewSize読み取り値まで0から繰り返すこと

T* newArray = new T[newSize]; 
if (newSize >= mSize) 
{ 
    for (int i = 0; i < newSize; ++i) 
     newArray[i] = mData[i]; 
} 

は予告:

+1

エラーは何ですか? – yizzlez

+1

あなたのコードは本当に冗長で、リファクタリングが必要です。 – Charles

+0

私は初心者であり、私が現在知っているツールを学ぼうとしています。私は練習でより良く、より効率的になることを知っています。 – David

答えて

0

は、このコードを見てみましょう。問題は、古い配列は0からmSize - 1までの有効なインデックスのみを持ち、0からnewSize - 1のインデックスではないため、配列の終わりを読み込みます。これは、すべての場合(oops!)未定義の動作につながりますが、プリミティブ型の場合、これは通常クラッシュを引き起こさず、文字列に対してのみ表示されます。

残りのコードを見て、ループの境界が正しいことを確認してください。正しく設定されていないループが少なくとも1つは見つかると思います。

また、valgrindのようなツールでは、これらのようなメモリエラーの診断に優れています。

完全な付随的な発見として、2つの割り当てと2つの割り当て解除を行う必要があるかどうかについて考えることもできます。 1つの新しい割り当てと1つの割り当て解除だけでこれを行うことができますか?

+0

valgrind以外にも、Clang Sanitizersの使用をお勧めします。私は個人的にはバングラデシュのClangのSantizersを好んでおり、その中にはgccでも使いやすいものがあります – Justin

+0

ありがとうございました。私はコードを見て、私が間違っていたのは、newSizeとmSizeを逆にしたもので、私は本質的に何も繰り返さなかったと思います。私はそれを「大きければ、新しいサイズを設定して、私たちが持っているものに書き出します」というように変更しました。残りのインデックスはヌルで、逆に新しいサイズが小さい場合は「newSizeに書き込みます。今すぐご利用ください! – David

0

mDataはタイプT*であると仮定すると、あなたは次のように、この何かを試すことができます。

キーポイント:

  • 大きさは以前と同じである場合、その後、何のサイズ変更はありません!
  • リサイズした配列を避けるために、大きいときにメモリが)(memsetのでwhipedさ
  • 機能のサイズを変更するあなたは一度だけコピーして、標準のmemcpy
  • を通じてこの関数は、型にとらわれないで、すべてのテンプレートで使用することができますメモリリーク
+1

'std :: fill'と' std :: copy'は本質的に同じことをしますが、より安全にタイプするのを除いては同じですか? – templatetypedef

+0

私は今知っている限られたツールでそれを書こうとしていました。 memset/memcpyをまだ学習していない。私はそれらが私の人生をずっと簡単にするだろうと確信しています! – David

関連する問題