在C中遇到标头之前尝试读取的分段错误

在C中遇到标头之前尝试读取的分段错误,c,segmentation-fault,C,Segmentation Fault,我不熟悉C,请原谅问题的简单性。我试图将函数作为lib编写,所以它必须是健壮的,能够不断地从串行端口读取一个字节的编辑:直到遇到一个头开始字节。如果找到它,它将读入头和负载的其余部分,并将其存储在结构中。我的代码的开头看起来像这样,将包括一些伪代码: soh_read = 0; bytes_read = 0; bytes_left = 1; do{ n = read(fd, buf + bytes_read, bytes_left); if(n < 0){

我不熟悉C,请原谅问题的简单性。我试图将函数作为lib编写,所以它必须是健壮的,能够不断地从串行端口读取一个字节的编辑:直到遇到一个头开始字节。如果找到它,它将读入头和负载的其余部分,并将其存储在结构中。我的代码的开头看起来像这样,将包括一些伪代码:

soh_read = 0;
bytes_read = 0;
bytes_left = 1;

do{
    n = read(fd, buf + bytes_read, bytes_left);
    if(n < 0){
        if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR){
            return -1;
        }
    }else{
        bytes_read += n;
        if(!soh_read){
            if(buf[0] != SOH){
                bytes_read = 0;
                continue;
            }
        }
        soh_read = 1;
        //read header ...
        //read payload ...

}while(timeout is not reached);

我假设如果没有遇到SOH,我可以将读取的字节重置为0,并再次尝试在buf[0]位置读取,覆盖它以前读取的垃圾。但这似乎是一个缓冲区溢出的情况,为什么会出现分段错误?但是为什么这不起作用呢?如果是这样,最好的方法是什么?我想从buf[0]开始,这样就可以很容易地跟踪每个消息字段。我只是想从这里的专家那里学习一下,谢谢。

您遗漏了一些对诊断当前代码问题至关重要的信息。最重要的一点可能是,你的SOH是否会在文件中出现得比你的buf中允许的时间晚

但也就是说,我认为我的做法会有所不同:既然你显然不需要,甚至根本不关心SOH之前的数据,为什么不把所有数据读入一个字符,在每次迭代时覆盖之前的值,在遇到SOH之后,只保存超过一个字节的数据,这样您就可以实际使用它了

do { 
    read(fd, buf, 1);
    if (n<0 && errno != EWOULDBLOCK && /* ... */)
       return -1;
} while (buf[0] != SOH and !timeout_reached);

// read the header here

您遗漏了一些对诊断代码中的问题至关重要的信息。最重要的一点可能是,你的SOH是否会在文件中出现得比你的buf中允许的时间晚

但也就是说,我认为我的做法会有所不同:既然你显然不需要,甚至根本不关心SOH之前的数据,为什么不把所有数据读入一个字符,在每次迭代时覆盖之前的值,在遇到SOH之后,只保存超过一个字节的数据,这样您就可以实际使用它了

do { 
    read(fd, buf, 1);
    if (n<0 && errno != EWOULDBLOCK && /* ... */)
       return -1;
} while (buf[0] != SOH and !timeout_reached);

// read the header here

你能发布一个完整代码的链接,把它放在pastebin或其他东西里吗;可能是问题所在,它可能会在ir找到标头之前溢出缓冲区。如果你不使用数据,用户的增量是多少?仅当您读取有用的datatitus时才递增,我认为如果不读取SOH字节,则不需要所有代码,它永远不会命中我的其余代码。这里的问题是将读取的字节重置为0,然后再次读取到缓冲区的该位置。我知道这是原因,因为它在第二次读取1字节时出错。我的代码的其余部分应该可以,这是我显式重置字节读取计数的唯一地方,原因是我想确保SOH在buf[0]中。字节读取还用于读取头和有效负载,并且这些都计算正确。我想我真正的问题是,我应该如何一直将一个字节读入buf[0],直到达到SOH?当你访问内存超过分配的界限时,通常会出现SEGFULT,不知道重置为0可能是什么问题。你可以发布一个完整代码的链接,将其放在pastebin或其他东西中吗;可能是问题所在,它可能会在ir找到标头之前溢出缓冲区。如果你不使用数据,用户的增量是多少?仅当您读取有用的datatitus时才递增,我认为如果不读取SOH字节,则不需要所有代码,它永远不会命中我的其余代码。这里的问题是将读取的字节重置为0,然后再次读取到缓冲区的该位置。我知道这是原因,因为它在第二次读取1字节时出错。我的代码的其余部分应该可以,这是我显式重置字节读取计数的唯一地方,原因是我想确保SOH在buf[0]中。字节读取还用于读取头和有效负载,并且这些都计算正确。我想我真正的问题是,在达到SOH之前,我如何将一个字节读入buf[0]中?当访问内存超过分配的界限时,通常会出现SEGFULT,不知道重置为0可能是什么问题,我想这就是我试图模拟的。我没有明确地这样做,因为我想用一个read语句保持它的整洁,尽管很明显它会被多次调用。我在OP中添加了更多的代码,这样你就可以看到我在做什么了。@Jack:如果你只想使用一次读取,那么明显的替代方法是在soh_读取为真时增加bytes_read only。就我个人而言,我想我更喜欢单独的电话阅读。您可以考虑将其分解为两个函数,以获得像SkIPToToHythErfd这样的东西;阅读标题;。我想这就是我想要模仿的。我没有明确地这样做,因为我想用一个read语句保持它的整洁,尽管很明显它会被多次调用。我在OP中添加了更多的代码,这样你就可以看到我所做的
杰克:如果你只想使用一次读取,显然的替代方法是在soh\u read为真时增加bytes\u read only。就我个人而言,我想我更喜欢单独的电话阅读。您可以考虑将其分解为两个函数,以获得像SkIPToToHythErfd这样的东西;阅读标题;。