我认为我的析构函数导致错误发生。你能帮我搞清楚为什么吗?

时间:2012-07-15 21:48:14

标签: c++ oop destructor

问题在于我的赋值运算符,我忘了在我的字符串类中为我的指针释放和重新分配内存。我一定不小心把它当成了一个复制构造函数;这对于为什么内存管理非常重要是一个很好的教训。感谢大家的帮助。

我已经实现了自己的字符串类,这似乎是调用堆栈中最后一个函数在它中断之前。

String::~String(){
    delete [] rep;
    len=0;
}

有人可以帮我理解问题所在吗?

这是调用它的函数

template <class T> 
void SList<T>::RemoveAfter(typename SList<T>::Iterator i){        
    assert(i.nodePointer !=0 && i.nodePointer->next!=0);
    Node *save = i.nodePointer -> next;
    i.nodePointer->next = i.nodePointer->next->next;
    delete save;

}

如果还有更多信息需要帮助我弄清楚为什么会发生这种情况让我知道。

顺便说一句,如果我使用int类型,我没有这个问题,所以我知道问题必须与我的字符串类一样......对吗?

根据要求提供更多信息:

struct Node{ // Node: Stores the next Node and the data.
    T data;
    Node *next;
    Node() {next =0;}
    Node(const T& a, Node *p = 0){data=a;next=p;}

};

错误:

  

Windows已在Algorithms.exe中触发了断点。   这可能是由于堆的损坏,这表明Algorithms.exe或它已加载的任何DLL中的错误。   这也可能是由于用户在Algorithms.exe具有焦点时按下F12。   输出窗口可能包含更多诊断信息。

中断的示例功能:

    String item1("Example"), item2("Example");
    SList<String> list1;        
    list1.AddFirst(item2);
    list1.AddFirst(item1);
    list1.AddLast("List Class");
    list1.AddLast("Functionality");

    SList<String>::Iterator i1;

    i1 = list1.Begin();     
    i1++;
    i1++;
    list1.RemoveAfter(i1);

有效的例子

    SList<int> list1;       
    list1.AddFirst(1);
    list1.AddFirst(2);
    list1.AddLast(3);
    list1.AddLast(4);

    SList<int>::Iterator i1;

    i1 = list1.Begin();     
    i1++;
    i1++;
    list1.RemoveAfter(i1);


    system("pause");

更多信息:

//Default Constructor
String::String(){
rep = new char[1];
rep[0] = '\0';
len = 0;
}  

//Constructor - Converts char* to String object
String::String(const char *s){
len=0;
const char *temp = s;
while(*temp){
    ++len;
    ++temp;
}//Sets len of rep to the length of s
rep = new char[len + 1];
for(int i=0; i<=len; ++i)
    rep[i]=s[i];
}

//Copy Constructor
String::String(const String &obj){
len=0;
char *temp = obj.rep;

while (*temp){
    ++len;
    ++temp;
}//Sets len of rep to length of obj.rep
rep = new char[len + 1];
for (int i = 0; i<=len; ++i)
    rep[i] = obj.rep[i];
}

//Assignment operator
const String& String::operator=(const String &rhs){
if (this != &rhs){
    len=0;
    char *temp = rhs.rep;
    while(*temp){
        ++len;
        ++temp;
    }//Sets len of this to length of rhs.rep
    for(int i = 0; i<=len;++i)
        rep[i]=rhs.rep[i];
}
return *this;
}

1 个答案:

答案 0 :(得分:2)

在赋值运算符中,您可能在char* rep指向的已分配区域的边界之外写入,这可能会破坏堆栈(即。导致未定义行为)。 / p>

当你稍后尝试释放这段内存时,一个损坏的堆栈可能会导致事情变成banans,这是一个非常合理的,这就是你在运行应用程序时收到的错误消息的原因。

正如消息本身所述“这可能是由于损坏了堆


如何解决我的问题?

在作业操作员中,您需要做三件事:

  1. this 中释放先前分配的内存(除非 this-&gt; len rhs.len 具有相同的值,如果是这样;跳过步骤 2。以及
  2. rhs.rep 分配与 rhs 相同的内存量(即 rhs.len 字节)
  3. 更新 this-&gt; len 以表示新内容的长度
  4. 将存储在 rhs.rep 指向的内存中的字节复制到 this-&gt; rep 指向的内存段。
  5. 目前你只是在做第3步&amp; 4。