2013-05-04 50 views
1

我一直有這個問題一段時間了,我已經搜索了這種類型的錯誤,我相信它必須處理內存泄漏或指向什麼都沒有的指針。C++分割錯誤 - 核心轉儲

我一遍又一遍地檢查了我的代碼,我無法準確找到問題發生的位置,因爲我不知道如何調試它。即使我嘗試斷點代碼的第一行,它也會崩潰。

它從文件中讀取一堆ISBN並檢查它們是否有效。

雖然它看起來很多,但邏輯非常簡單。

這裏是我的代碼:

#include <iostream> 
#include <fstream> 
#include <iomanip> 
#include <list> 
#include <ctype.h> 
#include <string.h> 
#include <stdlib.h> 
#include <vector> 

using namespace std; 

class Isbn 
{ 
    private: 
    string isbnCode; 

    public: 

    Isbn() 
    {    
    } 

    Isbn(string isbn): isbnCode(isbn) 
    {    
    } 

    ~Isbn() 
    {    
    } 

    string getIsbn() 
    { 
     return isbnCode; 
    } 

    void setIsbn(string input) 
    { 
     isbnCode = input; 
    } 
}; 

void setListOfIsbn(const string filename, list<Isbn> &listOfIsbn); 
void validateIsbns(const list<Isbn> listOfIsbn, list<bool> &validations); 
void printValidations(const list<Isbn> listOfIsbn, 
    const list<bool> validations); 
string bToS(const bool bValue); 

int main(int argc, char *argv[]) 
{ 
    list<Isbn> listOfIsbn; 
    list<bool> validations; 

    string inputFile = argv[1]; 

    setListOfIsbn(inputFile, listOfIsbn); 
    validateIsbns(listOfIsbn, validations); 
    printValidations(listOfIsbn, validations); 

    return 0; 
} 

void setListOfIsbn(const string filename, list<Isbn> &listOfIsbn) 
{ 
    list<Isbn>::const_iterator iterator; 

    ifstream fin; 

    fin.open(filename.c_str()); 
    char ch; 
    string isbnCode; 

    while (!fin.eof()) 
    { 
     fin.get(ch); 

     if (ch == '\n') 
     { 
     Isbn isbn; 

     (isbn).setIsbn(isbnCode); 
     listOfIsbn.push_back(isbn); 
     isbnCode = "";   
     } 
     else 
     { 
     isbnCode.append(reinterpret_cast<const char*>(ch)); 
     } 
    } 
} 

void validateIsbns(const list<Isbn> listOfIsbn, list<bool> &validations) 
{ 
    list<Isbn>::const_iterator itr; 

    for (itr = listOfIsbn.begin(); itr != listOfIsbn.end(); itr++) 
    { 
     Isbn isbn = *itr; 
     string isbnCode = isbn.getIsbn(); 
     string isbnCodeReform = ""; 
     vector<int> products; 
     int sumOfProducts = 0; 
     unsigned int i; 

     for (i = 0; i < isbnCode.length(); itr++) 
     { 
     if(isalnum(isbnCode[i])) 
     { 
      isbnCodeReform[i] = isbnCode[i]; 
     } 
     } 

     for (i = 0; i < (isbnCodeReform.length() - 1); itr++) 
     { 
     if(isbnCodeReform[i] == 'X') 
     { 
      isbnCodeReform[i] = 10; 
     }   

     products[i] = isbnCodeReform[i] * (10 - i);  
     } 

     vector<int>::const_iterator itr; 

     for (itr = products.begin(); itr != products.end(); itr++) 
     { 
     sumOfProducts += products[*itr]; 
     } 

     if ((sumOfProducts % 11) == 0) 
     { 
     validations.push_back(true); 
     } 
     else 
     { 
     validations.push_back(false); 
     } 
    } 
} 

void printValidations(const list<Isbn> listOfIsbn, 
    const list<bool> validations) 
{ 
    list<Isbn>::const_iterator itr; 
    list<bool>::const_iterator itr2 = validations.begin(); 

    for(itr = listOfIsbn.begin(); itr != listOfIsbn.end(); itr++) 
    { 
     string validate = bToS(*itr2); 
     Isbn isbn = *itr; 
     cout << isbn.getIsbn() + ": " + validate + "\n"; 
     itr2++; 
    } 
} 

string bToS(const bool bValue) 
{ 
    if(bValue == 0) 
    { 
     return "False"; 
    } 
    else 
    { 
     return "True"; 
    } 
} 

任何幫助,將不勝感激!

+1

您需要一個調試器來提取堆棧跟蹤,以便知道它在哪裏崩潰。你在做什麼平臺? GCC? MSVC? – 2013-05-04 14:39:38

+0

因此,所有這些代碼甚至不是原始的段錯誤吧?當然會很好的將其縮小到某種特定的方法。 – 2013-05-04 14:40:16

+0

我從來不知道valgrind,現在嘗試,謝謝 – 2013-05-04 14:41:03

回答

5

我試過詳細儘可能多的明顯的錯誤,因爲我可以在下面。可能還有更多。有了這許多錯誤,顯然你正在採用錯誤的編程方法。首先,你應該清楚地考慮你正在編寫的代碼,僅僅寫一些看起來大致正確的代碼是不夠的,編程你必須得到正確的。其次,你寫的代碼質量太差了。你應該寫幾行代碼,在你寫更多之前讓它們工作。在這裏出現錯誤時你已經堆積了錯誤,所以很明顯你已經在做零點測試了。即使是專業人員也不行,更不用說初學者了。工作意味着工作,而不僅僅是編譯。由於該代碼顯示編寫大量編譯代碼非常容易。最後學會使用調試器,它將有助於加載。顯然你有一些複雜的客戶/服務器設置。忘記這一點,在你自己的機器上安裝一個編譯器和調試器。

isbnCode.append(reinterpret_cast<const char*>(ch)); 

是錯誤的

isbnCode += ch; 

是你想要的。除非你真的知道你在做什麼,否則不要使用reinterpret_cast。

while (!fin.eof()) 
{ 
    fin.get(ch); 

是檢查文件結尾的錯誤的方式

while (fin.get(ch)) 
{ 

是你想要的。

實際上整個void setListOfIsbn(const string filename, list<Isbn> &listOfIsbn)太複雜了。這並不完全一樣,但在三次更少的代碼

void setListOfIsbn(const string filename, list<Isbn> &listOfIsbn) 
{ 
    ifstream fin(filename.c_str()); 
    string isbnCode; 
    while (getline(fin, isbnCode)) 
     listOfIsbn.push_back(isbnCode); 
} 

此代碼是不正確

string isbnCodeReform = ""; 
    for (i = 0; i < isbnCode.length(); itr++) 
    { 
    if(isalnum(isbnCode[i])) 
    { 
     isbnCodeReform[i] = isbnCode[i]; 
    } 
    } 

因爲isbnCodeReform是一個零長度字符串,因此isbnCodeReform[i]是要失敗的。也許你的意思是這個

string isbnCodeReform = ""; 
    for (i = 0; i < isbnCode.length(); itr++) 
    { 
    if(isalnum(isbnCode[i])) 
    { 
     isbnCodeReform.push_back(isbnCode[i]); 
    } 
    } 

這是同樣的錯誤

vector<int> products; 
for (i = 0; i < (isbnCodeReform.length() - 1); itr++) 
{ 
    if(isbnCodeReform[i] == 'X') 
    { 
     isbnCodeReform[i] = 10; 
    }   

    products[i] = isbnCodeReform[i] * (10 - i);  
} 

同樣的產品是零長度數組,所以products[i]將失敗。同樣,你可能是指像

 products.push_back(isbnCodeReform[i] * (10 - i)); 

這是一個關於迭代器是如何工作的

for (itr = products.begin(); itr != products.end(); itr++) 
    { 
    sumOfProducts += products[*itr]; 
    } 

混淆你可以寫

for (itr = products.begin(); itr != products.end(); itr++) 
    { 
    sumOfProducts += *itr; 
    } 

,或者你可以寫

for (i = 0; i < products.size(); i++) 
    { 
    sumOfProducts += products[i]; 
    } 

什麼你有一個兩種不起作用的混合物。

+0

+/- 0是最好給一個人一條魚或教這個人釣魚?我真的不知道哪個更好,因此沒有投票權。 – msw 2013-05-04 15:25:21

+0

@msw好吧,SO並不是真的教C++的好地方。我試圖給出一些一般建議以及具體的錯誤。 – john 2013-05-04 15:30:03

+0

+1。對於兩種 - 在教魚的同時給予一條魚。 – SChepurin 2013-05-04 16:12:58

0

錯誤發生在這裏:

 isbnCode.append(reinterpret_cast<const char*>(ch)); 

如果你是鑄造一個字符(最有可能的一個數字)到const char * - 所以我們有一個字符的值,作爲一個指針。在任何有任何內存訪問檢查的系統上,幾乎肯定會失敗。

您應該將字符添加到您的字符串中。最簡單的方法是:

 isbnCode += ch; 
+0

非常感謝您的幫助,對於C++來說很新穎。實施了所有修復並使其工作。乾杯! – 2013-05-04 16:08:52