2009-11-29 93 views
1

我遇到了一些问题。在main中返回零时,我的程序会引发分段错误。程序结束时的段错误

主要功能如下:

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; 
} 

的评论zomg部分是使得程序崩溃的地步。 zomg指向char[20]。我在这方面的观点是设置数组的末尾,因为不知怎的,如果我不这样做,流读取的数据超过20个字节,但它只打印一个不必要的符号。

有趣的是,即使我写了这个之间的一些额外的代码并返回0它返回时引发错误。

只是为了万一你想看看cSendStream类:

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; 
}; 

和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); 
} 
+0

zomg! (抱歉,无法抗拒) – aib 2009-11-30 00:25:30

回答

6

zomg [20] = 0正在写一个超过分配数组的末尾,但很难猜测为什么会出现段错误。我的猜测是你聪明的编译器使用alloca来进行分配,并且你正在写入返回地址。

查看组件(通常为-S)以查看发生了什么可能很有趣。

+0

thx很多人;) – Pyjong 2009-11-29 22:22:32

5

你分配的数组char[20],其有效索引为0-19,但您试图访问索引20.导致段错误。

+0

是的,你正在摧毁堆栈,以便当main返回程序计数器被破坏时,我想象。 用Valgrind运行它,你会看到。 – MarkR 2009-11-29 21:59:11

+0

那么如何结束该数组而不将最后一个字节设置为零? – Pyjong 2009-11-29 22:02:54

+0

@stupid_idiot - 看到我的答案,你需要声明你的数组比你的数据大一个。 – ChrisF 2009-11-29 22:08:03

1

所以这里这个位分配的缓冲区大小说20:

new char[streamsize] 

但随后你试图去21字符:

buf[20] 

有你赛格故障。这些数组是基于零的,因此对于大小为20的数组,索引从0到19.

1

要扩展int3的答案,如果数据长度为20个字符,则需要声明一个长度为21个字符的数组这样你就可以用空终止字符“完成它”。如果你这样做,那么你的代码将工作,因为zomg[20]将是一个有效的数组中的条目。