【问题标题】:if statement doesn't seem to ever failif 语句似乎永远不会失败
【发布时间】:2013-11-28 02:48:32
【问题描述】:

我有一个循环,它遍历存储在缓冲区中的图像,一次抓取 1024 个字节,并将这个千字节作为 UDP 数据包发送出去。下面是相关的代码部分。

当curr*1024 大于buf.bytesused 时,为什么我的第二个if 语句if (buf.bytesused - curr*1024 > 1024) 不会失败?我陷入了一个无限循环,直到 memcpy 最终抛出一个段错误才会结束。我的 buf.bytesused 大约是 900,000,但它并没有循环大约 900 次,而是继续运行,即使 buf.bytesused - curr*1024 给出否定结果,肯定小于 1024。

如果不清楚:当 curr 很小时,buf.bytesused - curr*1024 > 1024 就像我期望的那样得到满足,然后运行第二个 if 块。但是,当 curr 变大时(甚至大到 buf.bytesused - curr*1024 为负数),第二个 if 块仍在运行,而不是在 else 之后的第三个块。

buf.bytesused 是一个无符号的 32 位整数。

  #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 时做错了什么吗?它不会将我的两个字符的值复制到我的缓冲区。

【问题讨论】:

  • 您确定问题出在 if 条件上吗?看起来您正在用udpBuf[0] 中的任何内容覆盖frameInfo,这意味着它极不可能永远保持为FRAME_END。编辑:哦,那些应该是相反的方式吗?您可能想查看memcpy 的参数列表,看看您是否正确使用它
  • buf.bytesused 是 size_t 还是其他无符号整数类型?如果是这样,减法将使用无符号算术完成,并且永远不会变为负数。
  • 对不起,如果我的问题不清楚。我希望这更清楚:当curr 很小时,buf.bytesused - curr*1024 > 1024 就像我期望的那样满足,并且运行第二个 if 块。然而,当curr 变大时(即使大到buf.bytesused - curr*1024 为负数),第二个if 块仍在运行,而不是else 之后的第三个块。我不明白为什么,但根据我的经验,这通常意味着我忽略了一些非常基本的东西。
  • 请更新问题以澄清它,而不是添加评论。你可以提供一些例子;您还可以为问题中的变量提供定义(类型信息)。
  • 发布您的其余代码,以便我们了解您是如何实现缓冲区的。没有人知道buf.bytesused 是什么意思。

标签: c loops boolean-logic


【解决方案1】:

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 为负数,否则这些条件不会因签名而导致问题。

我认为这应该可以解决您的问题。

【讨论】:

  • 这不太可能是问题。除非 buf.bytesused 小于 1024,否则即使 bytesused 是无符号的,此条件最终也会失败。我认为这不是问题所在。
  • @RedAlert - 未签名的结果可能立即 > 1024。
  • @Hot Licks - 他的代码中没有“结果”,但如果你在谈论 bytesused,那么如果它开始 > 1024 应该可以正常工作。随着 curr 的增加,最终表达式将评估到 0 到 1024 之间的某个值,这将导致条件失败。
  • 对不起,我从一开始就没有这个信息,但我已经更新了问题,表明 buf.bytesused 是一个无符号的 32 位 int,初始值为 921600。
  • @RedAlert - 我说的是(可能是无符号的)减法的结果。只需 curr 为 1 且 bytesused 为
【解决方案2】:

如果人们想知道,实际的问题就在这里:

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

frameInfo 在设置为FRAME_END 后会被覆盖,因此while (frameInfo != FRAME_END) 永远不会评估为假。这导致程序进入无限循环的事实导致 OP 错误地认为他的 if 语句是错误的。最好使用调试器而不是假设您知道问题所在!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 2018-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    相关资源
    最近更新 更多