2011-05-23 184 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来编译它,并且我没有你的数据文件......)但是你可以使用类似的方法来获得真正的罪魁祸首。