动态字符串数组

时间:2013-03-14 11:48:26

标签: c++ string

我对以下课程有疑问。我认为问题在于字符串数组,因为我做了两个其他的类,问题是相同的。当我运行该程序时,它会抛出“双重自由或腐败”,但我不认为任何双重腐败是可能的。输入字符串作为引用或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;
};

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

  

当我运行该程序时,它会抛出“双重自由或腐败”,但我不认为任何双重腐败是可能的。

受过教育的猜测:

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

您编写的客户端代码实例化(或通过值分配或返回或在std容器中存储)WareH实例,并且因为您没有定义复制构造函数和赋值运算符(请参阅“The Big Three “),他们最终复制源对象中的值。当删除这些实例中的第一个(彼此分配)时,它们将删除strs指针。

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

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

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

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