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 :: assign中的SIGSEGV分段错误(std :: string const&amp;)
虽然我在功能ifstream in("testdata.txt")
中加入了行getNexttransaction()
,但我没有收到任何错误。
出了什么问题?
答案 0 :(得分:4)
好吧,我没有阅读你的代码所以我不知道它的目的是什么,但如果它是一个通常的c ++应用程序而没有修改系统默认内存管理,你应该学习使用GDB。
http://www.unknownroad.com/rtfm/gdbtut/gdbsegfault.html
帮助大量删除那些令人讨厌的段错误,它只需要你花5分钟阅读并使用它,但可以节省你几小时的printf调试。 (对不起,但阅读那么多代码以找到对某些内存的错误引用会很难)
答案 1 :(得分:2)
你怎么能完全确定你的向量v
中有50个元素,而且数量不少?在这个while循环中,
while(j<50)
{
(*Trans.items)[(Trans.length1)++]=v[j];
j=j+2;
}
您正在访问向量v
的最多50个成员,因为您正在拨打v[j]
,而j
将最多访问49,但如果{{1}那么你会得到一个分段错误。由于您将v.size() != 50
初始化为仅5个元素,并且仅在您增加超过当前最大大小时调整大小,这意味着v
中至少有5个或更多成员,但这并不意味着将至少有50名成员。对于使用v
的值的第二个while循环也是如此。
答案 2 :(得分: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
来编译它,而我没有你的数据文件...)但你可以使用类似的方法来获得真正的罪魁祸首。
答案 3 :(得分:0)
编辑:(删除了有关解除引用Trans
的部分)
Translen
可能是您的问题。如果它小于50,那么在items
的{{1}}循环期间,您将超过share
和while(j<50)
数组的长度。杰森的回答阐述了这一点。