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