0

我对以下课程有疑问。我认为问题出在字符串数组上,因为我做了另外两个类,问题是一样的。当我运行该程序时,它会抛出“双重免费或损坏”,但我认为不可能有任何双重损坏。输入字符串作为引用或作为 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

当一个类管理资源并在其析构函数中释放它们时,您必须考虑三法则以确保复制一个对象不会导致两个对象管理相同的资源。

这就是这里发生的事情:默认的复制构造函数和复制赋值运算符将复制指针,为您提供两个对象,它们都将尝试在销毁时删除同一个数组。解决方案是:

  • 删除拷贝构造函数和拷贝赋值运算符,防止拷贝;或者
  • 实现它们以将字符串复制到新数组中,而不仅仅是指针;或者
  • 使用std::vector而不是自己管理内存分配。
于 2013-03-14T12:03:38.620 回答
0

当我运行该程序时,它会抛出“双重免费或损坏”,但我认为不可能有任何双重损坏。

有根据的猜测:

问题不在于您显示的代码,而在于客户端代码。这是我认为会发生的事情:

您编写了实例化(或按值分配或返回或存储在 std 容器中)WareH实例的客户端代码,并且由于您没有定义复制构造函数和赋值运算符(请参阅“三巨头”),它们最终会从您的源对象。当这些实例中的第一个(相互分配的)被删除时,它们会删除 strs 指针。

当第二个实例被删除时,它们会删除之前删除的相同 strs 指针(因为默认的复制构造函数和赋值运算符不会复制分配的内存,而只是复制指针)。

解决方案(如果确实是问题):

  • 工作(和坏)解决方案:为您的班级明确定义复制构造和赋值运算符。

  • 工作(和好的)解决方案:将您的实施strs为 astd::vector<std::string>而不是std::string*and cnt

于 2013-03-14T12:06:24.173 回答