0

次のクラスに問題があります。問題は文字列配列にあると思います.他の2つのクラスを作成しましたが、問題は同じでした. プログラムを実行すると、「二重解放または破損」がスローされますが、二重破損は可能ではないと思います。問題は、入力文字列を参照として、または Add メソッドの共通引数として使用する場合と同じです。

class WareH
{
        public:
        WareH(void)
        {
               first = true;
               rows = 1;
               inLine = 0;
               cnt = 0;
               max = 2;
               cL = 0;
               strs = new string[max];
        }
        ~WareH(void)
        {
               delete [] strs;
        }
        bool    Add(string& str, int ending)
        {
               if (first)
                     inLine++;
               else
                     cL++; 
               if (ending == 0)
               {
                     if (first)
                          first = false;
                     if (cL != inLine)
                          return false;
                     rows++;
               } 
               strs[cnt++] = str;
               Bigger();
               return true;
         }
         void Bigger(void)
         {
                if(max == cnt)
                {
                       max *= 2;
                       string* tmp = new string[max];
                       for (int i = 0; i < cnt; i++)
                              tmp[i] = strs[i];
                       delete [] strs;
                       strs = tmp;
                }
         }
         friend ofstream& operator<<(ofstream& of,WareH war)
         {
                for (int a = 0; a < war.cnt; a++)
                       of << war.strs[a] << endl;
                return of;
         }
private:
      bool first;
      int rows, inLine, cnt, max, cL;
      string* strs;
};
4

2 に答える 2

1

クラスがリソースを管理し、そのデストラクタでそれらを解放する場合、オブジェクトをコピーしても同じリソースを管理する 2 つのオブジェクトが発生しないように、3 つのルールを考慮する必要があります。

それがここで起こっていることです: デフォルトのコピー コンストラクターとコピー代入演算子はポインターをコピーし、破壊時に同じ配列を削除しようとする 2 つのオブジェクトを提供します。解決策は次のとおりです。

  • コピーを防ぐために、コピー コンストラクターとコピー代入演算子を削除します。また
  • それらを実装して、ポインターだけでなく、文字列を新しい配列にコピーします。また
  • std::vector自分でメモリ割り当てを管理するのではなく、使用してください。
于 2013-03-14T12:03:38.620 に答える
0

プログラムを実行すると、「二重解放または破損」がスローされますが、二重破損は可能ではないと思います。

ここでの推測:

問題は、あなたが示したコードではなく、クライアント コードにあります。これが私が思うことです:

インスタンスをインスタンス化する (または、値によって代入または返す、または std コンテナーに格納する) クライアント コードを作成し、コピー コンストラクターと代入演算子 (「ビッグ スリーWareH」を参照) を定義していないため、最終的に値をコピーすることになります。ソース オブジェクト。これらのインスタンス (互いに割り当てられている) の最初のインスタンスが削除されると、strs ポインターが削除されます。

2 番目のインスタンスが削除されると、以前に削除されたものと同じ strs ポインターが削除されます (既定のコピー コンストラクターと代入演算子は、割り当てられたメモリを複製せず、ポインターをコピーするだけであるため)。

解決策(それが実際に問題である場合):

  • 機能する(そして悪い)解決策:クラスのコピー構築と代入演算子を明示的に定義します。

  • 実用的な(そして良い)解決策:andの代わりにyourstrsを実装します。std::vector<std::string>std::string*cnt

于 2013-03-14T12:06:24.173 に答える