where the segmentation fault is generated in this code? [closed]
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;
}
While I am debugging with gdb, I am geting something like:
Programm recieved SIGSEGV segmentation fault in std::string::assign(std::string const &)
While I am including the line ifstream in("testdata.txt")
in function getNexttransaction()
, I am not getting any error.
What's going wrong?
well, i did not read your code so i dont know what its purpose is, but if its an usual c++ application and nothing to modify the systems default memory management, you should learn using GDB.
http://www.unknownroad.com/rtfm/gdbtut/gdbsegfault.html
helps a lot removing those nasty segfaults, it will just take you 5 minutes to read it and use it, but can save you hours of printf debugging. (sorry but reading through that much code to find a wrong reference to some memory would be hard-work)
How can you be absolutely sure that your vector v
will have 50 elements in it, and no amount that is less? In this while-loop,
while(j<50)
{
(*Trans.items)[(Trans.length1)++]=v[j];
j=j+2;
}
you're accessing up to 50 members for the vector v
since you're making calls to v[j]
, and j
will go up to 49, but if v.size() != 50
, then you're going to get a segmentation fault. Since you initialize v
to be only 5 elements, and only resize it if you increment past it's current max-size, that means will have at least 5 or more members in v
, but that does not mean there will be at least 50 members. The same is true for the second while-loop using the value of j
as well.
After hacking the code a bit so that it would compile. I get this from 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)
Line 88 is right inside your main read loop. Suggesting that your loop may be confused.
This may not be your problem. (As I had to comment out assure
to get it to compile, and I dont have your data file...) But you could use a similar method to get the real culprit.
EDIT: (Removed section about dereferencing Trans
)
Translen
might be your problem in this particular case. If it's less than 50, you're going to exceed the length of the items
and share
arrays during the while(j<50)
loop in getnextTransaction
. Jason's answer elaborates on this point.
精彩评论