2013-03-14 101 views
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; 
}; 
+1

请重新设置代码的格式。 – filmor 2013-03-14 11:50:48

+5

每当我在同一个句子中听到“动态”和“数组”时,我会考虑'std :: vector'。也许你也应该? – 2013-03-14 11:51:22

+0

学习圣歌... [三条规则...三条规则...三条规则...](http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29) – 2013-03-14 11:53:19

回答

1

当一个类管理资源,并释放他们的析构函数,你必须考虑Rule of Three确保复制的对象不会导致两个管理对象的相同的资源。

这就是在这里发生的事情:默认的复制构造函数和复制赋值操作符将复制指针,给你两个对象,它们都会试图在销毁时删除同一个数组。解决方案如下:

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

+1。但我会缩短它。 “除非你有'std :: vector'不能满足的要求,否则使用'std :: vector'。我在这里没有看到一个。 – 2013-03-14 12:04:59

0

当我运行程序,它抛出的“双免费或腐败”,但我不认为任何腐败的双重可能。

猜测这里:

的问题是不是还有你的代码,但在客户端代码。以下是我想要发生的事情:

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

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

解决方案(如果这是真的,问题):

  • 工作(坏)解决方案:显式定义复制构造和赋值运算符为你的类。

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

+0

但是我只用一个类的实例工作,即使我做了测试,发现析构函数只被调用过一次。 – user1890078 2013-03-14 13:09:35