2016-04-11 142 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 *'进行比较时不会被调用。 –