segmentation fault at end of the program
I've got a bit problem. My program throws segmentation fault when returning zero in main.
The main function looks like this:
int main(int argc, char* argv[]){
ifstream fs("test.dat", ios::binary);
cSendStream sendstr(&fs,20);
char *zomg=sendstr.data();
//zomg[20]=0;
sendstr.read(20);
cout<<"Buffer: "<<sendstr.开发者_开发技巧data()<<endl;
cout<<"Remaining: "<<sendstr.dataAvailable()<<endl;
sendstr.read(2);
cout<<"Buffer: "<<zomg<<endl;
cout<<"Remaining: "<<sendstr.dataAvailable()<<endl;
sendstr.read(10);
cout<<"Buffer: "<<zomg<<endl;
cout<<"Remaining: "<<sendstr.dataAvailable()<<endl;
cout<<"end..."<<endl;
return 0;
}
The commented zomg
part is the point which makes the program crash. zomg
is pointing on char[20]
. My point on that line is to set the end of the array because somehow if I don't do that the stream reads more data than 20 bytes, but it prints just one unnecessary symbol though.
Funny thing is that even if I write there some additional code between this and return 0 it throws fault first when returning.
Just for the case you wanted to see the cSendStream class:
cSendStream.h:
class cSendStream{
public:
cSendStream(std::istream*, int streamsize);
int read(int);
int dataAvailable();
char* data();
private:
void shift(int);
std::istream *source;
int streamsize;
char* buffer;
};
and the cSendStream.cpp:
#include "cSendStream.h"
cSendStream::cSendStream(std::istream *src, int size){
source=src;
streamsize=size;
buffer=new char[streamsize];
memset(buffer,0,streamsize);
}
int cSendStream::read(int i){
if(dataAvailable()<1 || i<=0){
return 0;
}
if(i>dataAvailable()){
i=dataAvailable()-1;
}
if(i>streamsize){
i=streamsize;
}
shift(i);
source->read(&(buffer[streamsize-i]),i);
return i;
}
int cSendStream::dataAvailable(){
int current=source->tellg();
source->seekg (0, std::ios::end);
int available = (int)(source->tellg())-current;
source->seekg (current);
return available;
}
char* cSendStream::data(){
return buffer;
}
void cSendStream::shift(int i){
char tmp[2048];
memcpy(tmp,buffer,streamsize);
memcpy(&(buffer[0]),&(tmp[i]),streamsize-i);
}
zomg[20]=0 is writing one past the end of the allocated array, but it is difficult to guess why the segfault is occurring. My guess is that your clever compiler is using alloca for the allocation and you are scribbling on the return address.
It might be fun to look at the assembly (usually -S) to see what's happening.
You are allocating an array of char[20]
, which has valid indices of 0-19, but you are trying to access index 20. That is causing the segfault.
So this bit here allocated the buffer with say size 20:
new char[streamsize]
But then you are trying to get to the 21st character:
buf[20]
There is you seg fault. The arrays are zero based so for an array of size 20 the indices go from 0 to 19.
To expand on int3's answer, if your data is 20 characters long you'll need to declare an array of 21 characters in length so that you can "finish it off" with the null termination character. If you did that then your code would work as zomg[20]
would be a valid entry in the array.
精彩评论