2013-10-18 34 views
1

所以我真的很沮喪,爲什麼會發生這種情況。我正在實現一個類似於std :: string的類,但這是使用鏈接列表而不是數組。我的重載運算符=由於某種奇怪的原因而不起作用。下面你可以看到,當我在方法內部打印指針時,字符串被複制到鏈接列表中,但是當我用此指針創建一個字符串對象時,控制檯會打印出無限垃圾。任何想法,我在這裏失蹤? (我只粘貼相關的代碼)鏈接列表overload overload =運行時錯誤

static int NumAllocations = 0; 

struct ListNode { 
    char info; 
    ListNode *next; 
    ListNode() : info('0'), next(0) {} 
    ListNode (char c) : info (c), next(0) {} 


}; 


class MyString { 
private: 
    ListNode *head; 
    static void delstring (ListNode *l); 
    static int strlen (ListNode * head); 
    static ListNode* strcpy (ListNode *dest, ListNode *src); 
public: 

MyString::MyString() : head(0) {} 

MyString::MyString (ListNode *l) : head(l) {} 

MyString::MyString(const MyString & s) { 
    if (s.head == 0) 
     head = 0; 
    else 
     head = strcpy(head, s.head); 
} 


MyString MyString::operator = (const MyString & s){    
    ListNode *renew = NULL; 
    if (head != s.head) { 
     if (head != 0) 
      delstring(this -> head); 

     head = strcpy(head, s.head); 
     // printList(head); (this prints out the string just fine, so it must be the         constructor ? but what about it ?! 

     MyString res (head); 
     return res; 
    } 
} 


MyString::~MyString(){ 
    if (head == 0) 
     return; 
    ListNode *temp = NULL; 
    do { 
     temp = head -> next; 
     delete head; 
     -- NumAllocations; 
     head = temp; 
    } while (temp != 0); 
} 

STATIC公共職能

ListNode* MyString::strcpy (ListNode *dest, ListNode *src){ 
    dest = new ListNode (src -> info); 
    ++ NumAllocations; 
    ListNode *iter = dest; 
    for (ListNode *ptr = src -> next; ptr != 0; ptr = ptr ->next){ 
     iter -> next = new ListNode (ptr -> info); 
     iter = iter -> next; 
     ++ NumAllocations; 
    } 
    return dest; 
} 


void MyString::delstring (ListNode *l){ 
    if (l == 0) 
     return; 
    ListNode *temp = NULL; 
    do { 
     temp = l -> next; 
     delete []l; 

     -- NumAllocations; 
     l = temp; 
    } while (temp != 0); 
    l = 0; 
} 
+0

類定義將很好地協助這項工作。節點管理代碼更是如此。我看到零爲什麼'dest'是* *提供給名爲'strcpy'的成員。它是按值傳遞的,不管它是在第一行中立即*丟失,所以它可能是一個局部變量而不是參數。該功能看起來可能是一個問題,所以我會從那裏開始。 – WhozCraig

+0

我添加了類定義。 strcpy是std :: string的成員函數,並且該類應儘可能相同,因此可以選擇名稱。就像我提到的那樣,列表被正確複製,因爲當我在返回前打印它時,它打印的很好,當我嘗試在operator = method的最後2行中創建一個具有該指針「頭部」的新對象時,它會混亂起來。 – Tangleman

回答

2

有兩件事情是從根本上錯了你的賦值運算符。

  • 並非所有的控制路徑都返回值。
  • 你不應該首先需要temp-final副本。該功能應該返回參考,特別是*this

所以......

MyString& MyString::operator = (const MyString & s) 
{    
    if (head != s.head) 
    { 
     if (head != 0) 
      delstring(this -> head); 
     head = strcpy(head, s.head); 
    } 
    return *this; 
} 

而且,我的一切在這個代碼中看到說ListNode對象單獨分配和連接在一起,但在delstring會員,你這樣做:

void MyString::delstring (ListNode *l) 
{ 
    if (l == 0) 
     return; 
    ListNode *temp = NULL; 
    do { 
     temp = l -> next; 
     delete []l; // <<==== vector delete of single allocated item 

     -- NumAllocations; 
     l = temp; 
    } while (temp != 0); 
    l = 0; 
} 

也許試試這個:

void MyString::delstring (ListNode *& l) 
{ 
    while (l) 
    { 
     ListNode *temp = l; 
     l = l->next; 
     delete temp; 
     --NumAllocations; 
    } 
} 

注意這需要一個指針引用而不是指針。一旦列表爲空(假設你在施工中正確終止了你的列表,並且看起來像你),它將把調用者的指針設置爲nullptr。

+0

我非常感謝你的幫助,對不起,我沒有包括更多的代碼,不想過度複雜的問題,但我想我做得更糟。我有一個寫入的副本構造函數,它現在包含在內以及析構函數中。我可以清楚地看到你的觀點。我會試着看看這是否會改變任何事情。 (但我懷疑析構函數做錯了什麼,因爲在這個方法中打印對象(print(objhead))會打印字符串,但是在main中,它是一個不同的故事 – Tangleman

+0

@Tangleman所以..拋出上半部分這個答案好嗎?好的... – WhozCraig

+0

@WhosCraig你真棒,上面的功能完美,但我仍然不明白爲什麼建立一個新的對象會搞砸,但它顯然是錯誤的。閱讀所有那些混亂的代碼! – Tangleman