2011-05-23 183 views
-1
class Transaction //TO store a transaction read from file 
{ 
public: 
    int maxlenth; 
    int length1,length2; 
    vector<string> *items; 
    vector<int> *share; 
    int tmv; 

    Transaction():maxlenth(Translen),length1(0),length2(0) 
    { 
     items=new vector<string>(maxlenth); 
     share=new vector<int>(maxlenth); 
    } 
    ~Transaction()  
    { 
     delete items; 
     delete share; 
    } 

    void set_tmv() 
    { 
     tmv=0; 
     for(int i=0;i<=length2;i++) 
       tmv=tmv+(*share)[i]; 
    }  
}; 


class Data 
{ 
public: 
    ifstream in; 

    Data(char *filename); 
    ~Data(); 

    Transaction& getnextTransaction(Transaction &Trans); 
}; 


Data::Data(char *filename) 
{ 
    ifstream in(filename); 
     assure(in,filename); 
} 

Data::~Data() 
{ 
    in.close(); 
} 

Transaction& Data::getnextTransaction(Transaction &Trans) 
{ 
    const char* delimiters = 
      " \t;()\"<>:{}[]+-=&*#.,/\\~"; 

    //ifstream in("testdata.txt"); 
    //set<string>Items1; 
    vector<string> v(5); 
    int i=0; 
    string line; 
    getline(in, line); 

    char* s =strtok((char*)line.c_str(), delimiters); 
    while(s) 
    { 
     if(i==v.size()) 
      v.resize(v.size()*2); 

     v[i++]=s; 
     s = strtok(0, delimiters); 
    } 
    vector<string>::iterator it=v.begin(); 
    int j=0; 
    while(j<50) 
    { 
     (*Trans.items)[(Trans.length1)++]=v[j]; 
     j=j+2; 
    } 
    j=1; 
    while(j<=50) 
    { 
     (*Trans.share)[Trans.length2++]=(atoi(v[j].c_str())); 
     j=j+2; 
    } 

    //copy(v.begin(),v.end(),ostream_iterator<string>(cout,"\n"); 
    return Trans; 
} 

int main() 
{ 
    Data d("testdata.txt"); 
    Transaction t,q; 

    d.getnextTransaction(t); 
    t.set_tmv(); 

    return 0; 
} 

雖然我用gdb調試,我在歌廳是這樣的:在的std :: string在這段代碼中產生分段錯誤?

PROGRAMM收到SIGSEGV段錯誤::分配(的std :: string常量&)

雖然我在函數getNexttransaction()中包含行ifstream in("testdata.txt"),但我沒有收到任何錯誤。

怎麼回事?

+0

我不認爲這個錯誤來自那裏,但要確保在字符串文字中使用'const char *'類型,就像'Data'的構造函數一樣。 – 2011-05-23 04:39:13

+1

在段錯誤後,bt(在gdb中)打印什麼? – 2011-05-23 04:44:30

+1

你*真的*想爲這個類定義一個拷貝構造函數和賦值操作符,或者當它們被隱式調用時會導致各種頭痛。 – 2011-05-23 04:44:40

回答

0

編輯:(約提領Trans刪除部分)

Translen可能是在這種特殊情況下你的問題。如果小於50,則在getnextTransactionwhile(j<50)循環期間,您將超過itemsshare陣列的長度。傑森的回答詳細闡述了這一點。

+0

成員訪問運算符的優先級高於解引用運算符,所以第一個語法應該沒問題。 – Jason 2011-05-23 05:01:42

+0

@Jason謝謝,我不記得它是什麼,但語法看起來令人懷疑。現在更新我的帖子... – 2011-05-23 05:04:49

4

好吧,我沒有讀你的代碼,所以我不知道它的目的是什麼,但如果它是一個通常的C++應用程序,沒有任何修改系統默認的內存管理,你應該學習使用GDB。

http://www.unknownroad.com/rtfm/gdbtut/gdbsegfault.html

有很大幫助去除那些討厭的段錯誤,它只是需要5分鐘閱讀它,使用它,但可以節省你的printf調試的時間。 (抱歉,但通過多讀碼找到一個錯誤的引用一些內存將是辛勤工作)

2

你怎麼能絕對確保你的矢量v將在其50個元素,並沒有量較少?在這個while循環,

​​

你所訪問多達50名成員爲載體v,因爲你打電話給v[j]j將上升到49,但如果v.size() != 50,那麼你會出現分段錯誤。由於您將v初始化爲僅5個元素,並且只在您增量超過當前最大值時調整其大小,這意味着v中至少有5個或更多成員,但這並不意味着至少有50個成員。對於使用j的值的第二個while循環也是如此。

1

在對代碼進行黑客處理之後,它會進行編譯。我從valgrind得到這個:

bash> valgrind ./a.out 

Invalid read of size 4 
==1827== at 0xDE038: std::string::assign(std::string const&) (in /usr/lib/libstdc++.6.0.4.dylib) 
==1827== by 0x282B: Data::getnextTransaction(Transaction&) (dummy.cpp:88) 
==1827== by 0x2947: main (dummy.cpp:110) 
==1827== Address 0x3ec6d8 is 4 bytes after a block of size 20 alloc'd 
==1827== at 0x1A6BB: operator new(unsigned long) (vg_replace_malloc.c:261) 

88行就在你的主讀循環中。建議您的循環可能會感到困惑。

這可能不是你的問題。 (因爲我不得不註釋掉assure來編譯它,並且我沒有你的數據文件......)但是你可以使用類似的方法來獲得真正的罪魁禍首。