Reputation: 2228
I have a loop which goes through an image stored in a buffer, grabs 1024 bytes at a time, and sends this kilobyte off as a UDP packet. Below is the relevant section of code.
Why doesn't my second if statement, if (buf.bytesused - curr*1024 > 1024)
fail when curr*1024
gets larger than buf.bytesused
? I'm getting stuck in an infinite loop, which doesn't end until memcpy finally throws a seg fault. My buf.bytesused is around 900,000, but instead of looping about 900 times, it just keeps going, even when buf.bytesused - curr*1024
gives a negative result, which is certainly less than 1024.
In case that wasn't clear: When curr is small, buf.bytesused - curr*1024 > 1024 is satisfied like I'd expect, and this second if-block is run. However, when curr get large (even so large that buf.bytesused - curr*1024 is negative), the second if-block is still being run, instead of the third block, after the else.
buf.bytesused
is an unsigned 32 bit int.
#define FRAME_START 0x0
#define FRAME_END 0xF
#define FRAME_MID 0xA
uint_32 buf.bytesused = 921600;
char frameInfo = FRAME_START;
char frameNum = i;
int curr = 0;
while (frameInfo != FRAME_END) {
if (curr == 0) {
frameInfo = FRAME_START;
memcpy(&frameInfo, &udpBuf[0], 1);
memcpy(&frameNum, &udpBuf[1], 1);
memcpy(buffers[buf.index].start + curr*1024, udpBuf + 2, 1024);
}else if (buf.bytesused - curr*1024 > 1024) {
frameInfo = FRAME_MID;
memcpy(&frameInfo, &udpBuf[0], 1);
memcpy(&frameNum, &udpBuf[1], 1);
memcpy(buffers[buf.index].start + curr*1024, udpBuf + 2, 1024);
} else {
frameInfo = FRAME_END;
memcpy(&frameInfo, &udpBuf[0], 1);
memcpy(&frameNum, &udpBuf[1], 1);
memcpy(buffers[buf.index].start + curr*1024, udpBuf + 2, (buf.bytesused % 1024));
}
if (sendto(s, udpBuf, BUFLEN, 0, &si_other, slen)==-1)
diep("sendto()");
curr++;
}
As an aside, could someone tell me what I'm doing wrong with memcpy? It doesn't copy the values of my two chars to my buffer.
Upvotes: 0
Views: 138
Reputation: 3816
In case people are wondering, the actual problem is here:
frameInfo = FRAME_END;
memcpy(&frameInfo, &udpBuf[0], 1);
frameInfo
is overwritten after it is set to FRAME_END
, so while (frameInfo != FRAME_END)
will never evaluate to false. The fact that this caused the program to enter an infinite loop lead the OP to mistakenly believe that his if statement was wrong. It's always good practice to use a debugger instead of assuming you know what the problem is!
Upvotes: 3
Reputation: 9415
if (buf.bytesused - curr*1024 > 1024) fail when curr*1024 gets larger than buf.bytesused
It may be problem when buf.bytesused
is unsigned
.
If it is negative and signed, then the above comparison should fail.
To solve, you can use simple maths too.
if (buf.bytesused > curr*1024 + 1024)
or
if (buf.bytesused > (curr + 1)*1024)
These conditions will not cause problem due to sign unless curr+1
is negative.
I think this should solve your problem.
Upvotes: 4