2016-03-21 120 views
-4

我寫了一個程序,從谷歌財務提取股票數據並執行買入/賣出決定。我用Visual Studio C++編寫它,它在Windows上工作正常,但是當我嘗試在ubautu上使用g++ -std=c++11 stock.cpp進行編譯時,我運行a.out時出現seg故障。我哪裏錯了?C++內存分割錯誤?

從主(),關於第二呼叫發生SMA()錯誤:

  decisionPoint_model_call(); 
      //this function call a function called SMA() twice to calculate two different moving averages 
      //the second time SMA() is called from inside decisionPoint_model_call() a seg. fault occurs 

GDB給我以下錯誤:

0xb7f42ac5 in std::basic_ostream >& std::operator<< , std::allocator >(std::basic_ostream >&, std::basic_string, std::allocator > const&)() from /usr/lib/i386-linux-gnu/libstdc++.so.6

的代碼如下:

stock.cpp

#include <iostream> 
#include <sstream> 
#include <string> 
#include <fstream> 
#include <vector> 
#include <deque> 


using namespace std; 

int numberOfDays; //total number of days 
int dayNumber = 0; //0 being the starting date 

struct each_day { 
    string date; 
    float open; 
    float high; 
    float low; 
    float close; 
    float volume; 
    float mov_avg[1]; 

}; 

each_day *day = nullptr; 

//store parced cotents in structure one day at a time 
void float2structure(string date, float open, float high, float low, float close, float volume) 
{ 
    if (dayNumber == 0) 
    { 
     day = new each_day[numberOfDays]; 
    } 

    day[dayNumber].date = date; 
    day[dayNumber].open = open; 
    day[dayNumber].high = high; 
    day[dayNumber].low = low; 
    day[dayNumber].close = close; 
    day[dayNumber].volume = volume; 

    if (dayNumber != numberOfDays) 
    { 
     dayNumber++; 
    } 



} 

void line2float(string line_string) //reads line and converts appropriate type 
{ 

    string date; 
    float open; 
    float high; 
    float low; 
    float close; 
    float volume; 

    string temp; 

    int dataBlocks = 1; 

    istringstream ss(line_string); 
    while (!ss.eof()) 
    { 
     switch (dataBlocks) 
     { 
     case 1: 
      getline(ss, date, ','); 
     case 2: 
      getline(ss, temp, ','); 
      if (temp == "-") { 
       temp = "0"; 
      } 
      open = stof(temp); 
     case 3: 
      getline(ss, temp, ','); 
      if (temp == "-") { 
       temp = "0"; 
      } 
      high = stof(temp); 
     case 4: 
      getline(ss, temp, ','); 
      if (temp == "-") { 
       temp = "0"; 
      } 
      low = stof(temp); 
     case 5: 
      getline(ss, temp, ','); 
      if (temp == "-") { 
       temp = "0"; 
      } 
      close = stof(temp); 
     case 6: 
      getline(ss, temp, ','); 
      if (temp == "-") { 
       temp = "0"; 
      } 
      volume = stof(temp); 
     } 

    } 
    float2structure(date, open, high, low, close, volume); 
} 

//gets line, sort in correct order, send each line to next function 
void lineGet(ifstream &inFile) 
{ 
    cout << "Reorganizing data... be patient..." << endl; 

    vector<string> lines_in_reverse; 
    string line; 
    while (getline(inFile, line)) 
    { 
     // Store the lines in reverse order. 
     lines_in_reverse.insert(lines_in_reverse.begin(), line); 

    } 

    numberOfDays = lines_in_reverse.size() - 1; 

    for (int x = 0; x < numberOfDays; x++) 
    { 
     line2float(lines_in_reverse[x]); 
    } 


} 

//calculed the SMA and stores that in data.mov_avg[x] 
void SMA(int movingAvg, int mv_num) 
{ 
    deque <float> sma; 
    float smaSize = (float)movingAvg; 

    float sum_of_elems = 0; 

    for (dayNumber = 0; dayNumber < numberOfDays; dayNumber++) 
    { 
     cout << day[dayNumber].date << " " <<dayNumber<<endl; 

     if (dayNumber <= smaSize - 1) 
     { 

      sma.push_front(day[dayNumber].close); 

      day[dayNumber].mov_avg[mv_num] = 0; //ERROR HERE? 


      if (dayNumber == smaSize - 1) 
      { 
       for (float n : sma) { 
        sum_of_elems += n; 
       } 

       day[dayNumber].mov_avg[mv_num] = sum_of_elems/smaSize; 

      } 


     } 
     else 
     { 
      sum_of_elems = 0; 
      sma.pop_back(); 
      sma.push_front(day[dayNumber].close); 

      for (float n : sma) 
      { 
       sum_of_elems += n; 
      } 

      day[dayNumber].mov_avg[mv_num] = sum_of_elems/smaSize; 

     } 

    } 

} 

//function to analyze data and report trades 
void decisionPoint_model(string startDate) 
{ 
    dayNumber = 0; 
    bool holdingLong = false; 
    bool shortSell = false; 
    float totalProfit = 0; 
    float buyPrice; 
    float sellPrice; 
    float shortPrice; 
    float coverPrice; 

    //loop though each day, compare moving averages, buy and sell based on moving averages 
    for (; dayNumber < numberOfDays; dayNumber++) { 
     //cout << day[dayNumber].moving_avg[0] << " " << day[dayNumber].moving_avg[1] << endl; 
     if (day[dayNumber].mov_avg[1] != 0) { 

      if (day[dayNumber].mov_avg[0] < day[dayNumber].mov_avg[1] && holdingLong == true) { 
       //sell 
       sellPrice = day[dayNumber + 1].open; 
       totalProfit += (sellPrice - buyPrice); 
       cout << "Sell: $" << day[dayNumber + 1].open << " on " << day[dayNumber + 1].date << endl; 
       cout << "Profit from trade: $" << sellPrice - buyPrice << endl; 
       cout << "Total profit: $" << totalProfit << endl; 
       cout << endl; 
       holdingLong = false; 
      } 
      if (day[dayNumber].mov_avg[0] < day[dayNumber].mov_avg[1] && shortSell == false) { 
       //short 
       shortPrice = day[dayNumber + 1].open; 
       cout << "Short: $" << day[dayNumber + 1].open << " on " << day[dayNumber + 1].date << ", "; 
       shortSell = true; 
      } 
      if (day[dayNumber].mov_avg[0] > day[dayNumber].mov_avg[1] && shortSell == true) { 
       //cover 
       coverPrice = day[dayNumber + 1].open; 
       totalProfit += (shortPrice - coverPrice); 
       cout << "Cover: $" << day[dayNumber + 1].open << " on " << day[dayNumber + 1].date << endl; 
       cout << "Profit from trade: $" << shortPrice - coverPrice << endl; 
       cout << "Total profit: $" << totalProfit << endl; 
       cout << endl; 
       shortSell = false; 
      } 
      if (day[dayNumber].mov_avg[0] > day[dayNumber].mov_avg[1] && holdingLong == false) { 
       //buy 
       buyPrice = day[dayNumber + 1].open; 
       cout << "Buy: $" << day[dayNumber + 1].open << " on " << day[dayNumber + 1].date << ", "; 
       holdingLong = true; 
      } 
     } 

    } 
    cout << endl; 
    cout << "Total profits from strategy: $" << totalProfit << endl; 
    cout << endl; 
} 


void decisionPoint_model_call() { 


    cout << "testing end" << endl; 
    cout << "\nWe are going to perfrom a decision point analysis." << endl; 
    cout << "This requires two moving averages relatively close by (eg. 10 and 15 day moving averages)." << endl; 
    cout << endl; 
    int movingavg; 
    cout << "Set the first moving average (ex. 10):"; 
    cin >> movingavg; 
    SMA(movingavg, 0); 

    cout << endl; 
    cout << "Set the second moving average (ex. 15):"; 
    cin >> movingavg; 
    SMA(movingavg, 1); //ERROR OCCURS THE SECOND TIME WE CALL SMA() 



    cout << "\nData stretches from: " << day[0].date << " to " << day[numberOfDays - 1].date << endl; 
    cout << "NO ERROR" << endl; 
    string startDate; 
    cout << "Enter a date to begin analysis: "; 
    cin >> startDate; 
    cout << endl; 

    decisionPoint_model(startDate); 
    cout << "Open price on first day (given data): $" << day[0].open << endl; 
    cout << "Close price on last day (given data): $" << day[numberOfDays - 1].close << endl; 
    cout << "For a total price change of: $" << day[numberOfDays - 1].close - day[0].open << endl; 
    cout << endl; 

} 
void file_get() { 


functionStart: 
    string filename; 
    cout << "\nEnter file name (ex. goog.csv):"; 
    cin >> filename; 

    ifstream inFile(filename.c_str()); 
    if (inFile.is_open()) { 
     cout << "\nLoading file...\n" << endl; 
     lineGet(inFile); 
     inFile.close(); 
    } 
    else { 
     cout << "No file was found on disk, retrieving one from the web..." << endl; 
     system("python stockFetch.py"); 
     goto functionStart; 
    } 
} 



int main() 
{ 

    cout << endl; 
    cout << "What type on analysis would you like to perform?" << endl; 
    cout << "1. Decision Point Analysis - based on historical data." << endl; 
    cout << endl; 
    cout << "Enter number: "; //only number that works is 1 currently 
    int analysisNumber; 
    cin >> analysisNumber; 

    switch (analysisNumber) { 
    case 1: 
     file_get(); 
      //order of calls: 1.file_get() -> 2.lineGet() -> 3.line2float() -> 4.float2structure() 
      //function 2 - 4 are called over and over again to store each line from the cvs file to the structure 

     decisionPoint_model_call(); 
      //this function call function called SMA() twice to calculate two different moving averages 
      //the second time SMA() is called from inside decisionPoint_model_call() a seg. fault occurs 



    } 

    system("pause"); 
    return 0; 
} 

要獲取股票數據文件,您需要從here獲取csv文件,並將其保存爲aapl.csv

或者保存下面的python文件,因爲如果在磁盤上找不到.csv文件,C++程序會調用它。

stockFetch.py​​

import sys, os, urllib 

#get the csv file from google finance 
tickerSymbol= raw_input('Enter the ticker symbol: ') 
startDate = raw_input('Enter the start date(Ex. Jan 20, 2015): ') 
endDate = raw_input('Enter the end date: ') 
startDate.replace (" ", "+") 
startDate.replace (",", "2C") 
endDate.replace (" ", "+") 
endDate.replace (",", "2C") 

url = "http://www.google.com/finance/historical?q="+str(tickerSymbol)+"&startdate="+str(startDate)+"&enddate="+str(endDate)+"&output=csv" 


urllib.urlretrieve(url, str(tickerSymbol)) 
if os.path.isfile(str(tickerSymbol)): 
     os.rename(str(tickerSymbol), str(tickerSymbol)+".csv") 
     print ("--File Fetched--") 
     sys.exit() 

print ("--Could not find file--") 
+1

請張貼[MCVE]。關鍵字 - 最小。 –

+0

或使用調試器。您至少需要使用基本的調試技巧來查找崩潰發生的位置,然後問您是否不明白原因。你可能會對矢量和字符串的大小做出假設,或者做一些糟糕的事情,比如從無符號值減去1。 – paddy

回答

0

我不知道這是否是唯一的錯誤,而且是一個錯誤。

可以定義大小1

float mov_avg[1]; 

each_day::mov_avg但在位置用來2

day[dayNumber].mov_avg[mv_num] = 0; //ERROR HERE? (yes, when mv_num == 1) 
[...] 
day[dayNumber].mov_avg[mv_num] = sum_of_elems/smaSize; 
[...] 
day[dayNumber].mov_avg[mv_num] = sum_of_elems/smaSize; 
[...] 
if (day[dayNumber].mov_avg[1] != 0) { 
    if (day[dayNumber].mov_avg[0] < day[dayNumber].mov_avg[1] && holdingLong == true) { 
[...] 

嘗試限定

float mov_avg[2];