2013-11-28 4 views
0

У меня есть цикл, который проходит через изображение, хранящееся в буфере, занимает 1024 байта за раз и отправляет этот килобайт в виде UDP-пакета. Ниже приведен соответствующий раздел кода.Если инструкция, кажется, никогда не срабатывает

Почему мой второй оператор if, if (buf.bytesused - curr*1024 > 1024) не работает, когда curr*1024 получает больше buf.bytesused? Я застрял в бесконечном цикле, который не заканчивается, пока memcpy, наконец, не вызовет ошибку seg. Мой buf.bytesused составляет около 900 000, но вместо того, чтобы зацикливать около 900 раз, он просто продолжает двигаться, даже когда buf.bytesused - curr*1024 дает отрицательный результат, который, конечно, меньше 1024.

В случае, если это было непонятно: мало, buf.bytesused - curr * 1024> 1024 выполняется, как я ожидал, и этот второй if-блок запускается. Однако, когда curr становится большим (даже настолько большим, что buf.bytesused - curr * 1024 отрицательный), второй if-блок все еще выполняется, а не третий блок, после else.

buf.bytesused - неподписанный 32-битный 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++; 
    } 

Как в стороне, может ли кто-нибудь сказать мне, что я делаю неправильно с memcpy? Он не копирует значения моих двух символов в буфер.

+0

Вы уверены, что проблема связана с этим условием? Похоже, вы переписываете 'frameInfo' с тем, что находится в' udpBuf [0] ', что означает, что он вряд ли когда-либо останется как' FRAME_END'. edit: oh, должны ли они быть наоборот? Возможно, вы захотите просмотреть список параметров для 'memcpy' и посмотреть, правильно ли вы используете его. –

+2

Является ли' buf.bytesused' 'size_t' или другим целым целым числом без знака? Если это так, вычитание будет выполнено с использованием арифметики без знака и никогда не будет отрицательным. –

+0

Извините, если я не был в этом вопросе. Надеюсь, это будет более ясно: когда 'curr' мал,' buf.bytesused - curr * 1024> 1024' выполняется, как я ожидал, и этот второй if-блок запускается. Однако, когда 'curr' становится большим (даже настолько большим, что' buf.bytesused - curr * 1024' отрицательный), второй if-блок все еще выполняется, а не третий блок, после 'else'. Я не понимаю, почему, хотя по моему опыту это обычно означает, что я пропускаю что-то очень основное. – WhiteHotLoveTiger

ответ

3

В случае люди задаются вопросом, реальная проблема здесь:

frameInfo = FRAME_END; 
memcpy(&frameInfo, &udpBuf[0], 1); 

frameInfo переписывается после того, как он установлен в FRAME_END, так while (frameInfo != FRAME_END) никогда не будет оценивать ложь. Тот факт, что это заставило программу войти в бесконечный цикл, заставляет OP ошибочно полагать, что его утверждение if было неправильным. Всегда хорошая практика использовать отладчик вместо того, чтобы предположить, что вы знаете, в чем проблема!

4

if (buf.bytesused - curr*1024 > 1024) fail when curr*1024 gets larger than buf.bytesused

Это может быть проблемой, когда buf.bytesused является unsigned.

Если это отрицательный и подписанный, то приведенное выше сравнение не должно быть выполнено.

Чтобы решить, вы можете использовать простую математику тоже.

if (buf.bytesused > curr*1024 + 1024) 

или

if (buf.bytesused > (curr + 1)*1024) 

Эти условия не будут вызывать проблемы из-за знак, если curr+1 не является отрицательным.

Я думаю, что это должно решить вашу проблему.

+1

Это вряд ли будет проблемой. Если buf.bytesused меньше 1024, это условие в конечном итоге не сработает EVEN, если bytesused не имеет знака. Я не думаю, что это не так. –

+0

@RedAlert - Результат без знака может быть> 1024 с места в карьер. –

+0

@Hot Licks - в его коде нет «результата», но если вы говорите о байтах, то он должен работать нормально, если он запускается> 1024. По мере того, как количество шагов увеличивается, в конечном итоге выражение будет оцениваться в диапазоне от 0 до 1024, что приведет к сбою условия. –

Смежные вопросы