2016-03-28 37 views
0

下面的代码应该实现我自己的字符串类。类似于如果你想创建这样的String s = "Hi";。我在销毁时遇到错误,并获取到delete[] data的部分。是说当我离开堆缓冲区时,我在写信。这些不是cstrings,所以在我的字符串末尾没有空字符。删除字符指针越来越堆错误

这里是我的转换/默认构造函数:

String346::String346(const char * oldString) : data(NULL), size(static_cast<unsigned int>(strlen(oldString))){ 
    data = new(std::nothrow) char[size]; 
    for (unsigned int i = 0; i <= getSize(); i++){ 
     data[i] = oldString[i]; 
    } 
} 

由于这些功能需要支持的功能链接,我要把我的,涉及到我的问题,这两个功能之一,如果一个String346对象传递或者一个char *中传递

串联其中char *在传递函数:

String346 & String346::concat(const char * catString) { 
    String346 newCatString(catString); 
    concat(newCatString); 
    return (*this); 
} 

级联功能,其中String346对象传入:

String346 & String346::concat(const String346 & catString) { 
     String346 tempData(data); 
     size = tempData.getSize() + catString.getSize(); 
     destroy(); 
     data = new (std::nothrow) char[size]; 
     if (data == NULL){ 
      std::cout << "Not enough space to concatinate this string." << std::endl; 
     } 
     else{ 
      unsigned int index = 0; 
      for (unsigned int i = 0; i < getSize(); i++){ 
       if (i < tempData.getSize()){ 
        data[i] = tempData.data[i]; 
       } 
       else{ 
        data[i] = catString.data[index]; 
        index++; 
       } 
      }  
     } 
     return (*this); 
    } 

我破坏功能,做所有的工作对象的破坏也很简单。它包含以下三行:

delete[] data; 
    data = NULL; 
    size = 0; 
    return; 

回答

1

你的构造分配char阵列含有size元素。

然后,您的构造函数似乎将size+1字符复制到数组(我假设getSize()返回size)。

因此,构造函数代码在数组的末尾运行,并且破坏了分配数组末尾的一个字节。

P.S. static_cast不是必需的,只会使代码更加混淆。

0

第一行中的concat方法:

String346 tempData(data); 

通行证一个char *你的构造函数不为NULL终止,所以调用strlen将越过字符串的结尾。

接下来的两行也不起作用:

size = tempData.getSize() + catString.getSize(); 
    destroy(); 

destroysize回到零,这意味着你的方法的其余部分将不会做任何事情。

您应该尝试通过调试器并单步执行此操作 - 然后您可以在每个步骤检查变量的值,并确保您的程序正在按照您的期望执行。另外,如果你有一个在析构函数中被释放的成员变量,你应该查看“三个规则”或“五个规则”,以确保事情不会被释放两次。