2013-05-07 31 views
-1

我有這樣一個返回Customer對象(不是指針)的函數:調用通過一個指針的函數 - 訪問衝突讀取位置

Customer CustomerList::retrieve(const int index) const{ 
     if (index<1 || index>size) 
       return false; 
     else{ 
       Node *cur = find(index); 
       return (cur->data); 
     } 
} 

該函數從CustomerList得到一個Customer對象(這是一個鏈表)。

我試圖操縱在列表中Customer具有以下功能(此功能增加了一個AccountCustomer對象。)

list.retrieve(i).addAccount(acc); 

但是這個函數調用後,Customer對象CustomerList不更改。我假設原因是我返回了一個Customer對象的副本,而不是對象本身。

因此,爲了返回客戶的地址並正確操作它,我對我的功能進行了以下更改。

Customer* CustomerList::retrieve(const int index) const{ 
     if (index<1 || index>size) 
       return false; 
     else{ 
       Node *cur = find(index); 
       return &(cur->data); 
     } 
} 

,並調用操縱功能類似:

list.retrieve(i)->addAccount(acc); 

但它給了我一個「訪問衝突讀取位置0x00000044。」錯誤。我想學的是:

  1. 爲什麼它不能操縱Customer對象?我的假設是否正確?
  2. 當我更改我的函數和函數調用後,它爲什麼會給我上面提到的錯誤?
+0

當你的返回類型是'Customer'時,你如何做'返回false';?將「bool」轉換爲「Customer」是否有意義? – 2013-05-07 14:59:39

+1

你有沒有檢查'cur'是否爲NULL? – Chethan 2013-05-07 15:00:32

+0

向我們展示客戶類別定義 – maverik 2013-05-07 15:00:39

回答

1

爲什麼不在第一位操作Customer對象?我的假設是否正確?

正如你所說,你正在返回一個副本並對其進行操作,使列表中的一個不受影響。

當我更改我的函數和函數調用後,爲什麼它會給我上面提到的錯誤?

的幾乎是肯定的,因爲這:

return false; 

,將返回一個空指針的指數超出範圍。如果這是你想要的行爲,那麼你就需要取消引用指針前檢查:

if (Customer * c = list.retrieve(i)) { 
    c->addAccount(acc); 
} else { 
    // handle the error? 
} 

和,出於禮貌,你應該返回的東西,看起來更像是一個空指針如nullptrNULL,或者0

拋出異常可能是一個更好的主意(可能std::range_error);那麼如果函數返回,調用者可以認爲指針是有效的。在這種情況下,它也可能會更好返回一個參考,而不是一個指針,使代碼非常喜歡你原來的例子:

Customer & CustomerList::retrieve(const int index) const{ 
    if (index<1 || index>size) 
      throw std::range_error("Customer index out of range"); 
    else{ 
      Node *cur = find(index); 
      return (cur->data); 
    } 
} 

list.retrieve(i).addAccount(acc); // Does exactly what you'd expect 

我也可以考慮移動範圍檢查到find功能,如果這似乎適當。

0
  1. 爲什麼不操縱它排在首位客戶對象?

是的你是對的。通過defualt其調回by value不是通過引用,所以List中的原始對象不被修改。

  1. 後,我改變我的函數和函數調用,爲什麼它給了我我上面提到的錯誤?

我認爲你需要共享的addAccount方法的代碼。問題可能在裏面。 然後考慮與原始代碼return by value它是正常工作(無一例外)。