2016-04-11 76 views
0

由於某些原因,我得到「無效的讀取大小4」錯誤,我找不出來。我在網上搜索了一個答案,並沒有真正幫助我的代碼。總結一下我的代碼,它是一個股票交易模擬器。用戶將顯示選項,然後他們可以選擇他們想要做的事情。現在我遇到了「賣出股票」的問題。這是它的樣子。C++無效的讀取大小4 valgrind

Stock* newStock = new Stock(); 
view->getStockData(newStock); 

Stock* s = stocks->findElement(newStock); 

if(s->getAOS()-newStock->getAOS() > 0) { // There is still some shares remaining 
    // Haven't done this yet   

} else if (s->getAOS()-newStock->getAOS() == 0) { // There is no shares remaining 
     double result = s->calculate(newStock->getPrice(), s->getPrice(), s->getAOS()); 
     view->printResults(result, 0); 

     stocks->remove(newStock); 

} else { // Resulted with a negative value 
    // Haven't done this yet  
} 

view-> getStockData(newStock);看起來是這樣的:

void UImanager::getStockData(Stock* stock) { 
    // Initializing all the stock data 
    string str = ""; 
    string symbol, companyName; 
    double price; 
    int  amountOfShares; 

    cout << endl << "Enter the stock's symbol (e.g. AAPL): "; 
    getline(cin, symbol); 

    cout << endl << "Enter the companies name: "; 
    getline(cin, companyName); 

    cout << endl << "Enter the price of the stock: "; 
    getline(cin, str); 
    stringstream ss(str); 
    ss >> price; 
    str = ""; 

    cout << endl << "Enter the amount of shares: "; 
    getline(cin, str); 
    stringstream ss1(str); 
    ss1 >> amountOfShares; 
    str = ""; 

    Stock* tmpStock = new Stock(symbol, companyName, price, amountOfShares); 
    *stock = *tmpStock; 
    delete tmpStock; 
} 

股票類看起來是這樣的:

Stock::Stock(string s, string c, double p, int aOS) { 
    symbol = s; 
    companyName = c; 
    price = p; 
    amountOfShares = aOS; 
    fee = 10; 
} 

string Stock::getSymbol()  { return symbol; } 
string Stock::getCompanyName() { return companyName; } 
double Stock::getPrice()  { return price; } 
int Stock::getAOS()   { return amountOfShares; } 
int Stock::getFee()   { return fee; } 

bool Stock::operator==(Stock& s) { 
    if (this->getSymbol() == s.getSymbol()) { 
     return true; 
    } 

    return false; 
} 

// More below this, but that code doesn't matter for this problem 

而且我存儲在模板DLIST中,我所做的股票。這是findElement(T *):

template <class T> 
T* Dlist<T>::findElement(T* item) { 
    Node<T>* currNode = head; 

    while (currNode != 0) { // iterate through the Dlist 
     if (currNode->data == item) { // uses the operator overloaded == from Stock 
      return currNode->data; 
     } 

     currNode = currNode->next; 
    } 

    // gets to this point if nothing was found 
    return 0; 
} 

這是Valgrind的說:

==2459== Invalid read of size 4 
==2459== at 0x804A4EC: Stock::getAOS() (in /home/student/Desktop/Stock Paper Trading/spt) 
==2459== by 0x8049356: SPTcontrol::launch() (in /home/student/Desktop/Stock Paper Trading/spt) 
==2459== by 0x8048F8D: main (in /home/student/Desktop/Stock Paper Trading/spt) 
==2459== Address 0x10 is not stack'd, malloc'd or (recently) free'd 
==2459== 
==2459== 
==2459== Process terminating with default action of signal 11 (SIGSEGV) 
==2459== Access not within mapped region at address 0x10 
==2459== at 0x804A4EC: Stock::getAOS() (in /home/student/Desktop/Stock Paper Trading/spt) 
==2459== by 0x8049356: SPTcontrol::launch() (in /home/student/Desktop/Stock Paper Trading/spt) 
==2459== by 0x8048F8D: main (in /home/student/Desktop/Stock Paper Trading/spt) 

所以據我所知,它告訴我,有什麼不對的發現之後,從我的股票類獲取信息它在Dlist中,但我真的不明白爲什麼或如何解決它?任何幫助將不勝感激。謝謝。

+0

我注意到你沒有檢查'Stock * s = stocks-> findElement(newStock)'返回null – vu1p3n0x

+0

是的,我檢查s是否爲空,我發現它是。現在我正在跟蹤這個問題,看起來問題在於我的操作符重載==,因爲我把cout的item-> getSymbol()和currNode-> data-> getSymbol()放在了一起,它們都是「AAPL」 (我要測試的東西),但它似乎currNode->數據==項目由於某種原因返回false – Str8UpEliTe

回答

3

它看起來好像s是空指針,因爲Dlist::findElement正在返回空指針。

大的線索是valgrind抱怨的地址。你看到它說「地址0x10不堆棧,malloc'd或最近free'd」?這是非常不尋常的(閱讀:幾乎完全聽不到)真正的地址是如此接近零;這幾乎總是意味着你的代碼遇到了一個空指針,它在大多數系統上恰好由零地址表示,然後對其進行了一些算術運算(例如,如果Stock在地址0,那麼它的amountOfShares ?在地址16 = 0x10,也許)。

您可以通過添加一些明確檢查空指針的代碼,或者通過在調試器中運行代碼並逐步完成代碼來檢查。

如果我的猜想是正確的(或者如果它是錯誤的,但一些類似的猜想是正確的)將是爲什麼你從Dlist::findElement得到空指針。但我會讓你爲自己工作。

+0

哦好吧,現在我知道從哪裏開始修復它。謝謝 – Str8UpEliTe

+0

這個問題似乎是我的運算符重載函數,但我不明白爲什麼?在findElement中,我將if(currNode-> data == item)更改爲if(currNode-> data-> getSymbol()== item-> getSymbol())(這明顯違背了模板化dlist的目的)只是爲了測試它它確實有用?它似乎甚至沒有調用運算符重載==因爲我把cout語句放在它裏面,而且他們從來沒有打印到控制檯上?你有什麼想法爲什麼這樣做? – Str8UpEliTe

+0

我們沒有'Node'類的定義,但是如果你可以說'currNode-> data-> getSymbol()'',那麼我認爲'節點 :: data'的類型是'T * '而不是'T'。在這種情況下,當你試圖比較其中兩個時,你會得到一個指針比較。您的'operator =='用於比較兩個'Stock's,並且在兩個'Stock *'進行比較時不會被調用。 –