我偶然发现了一个持续存在的问题,似乎没有一个合理的解释。问题似乎存在于for (i = size - 1; i >= 0; i--) {etc.}的for循环中,其中size是存储在内存缓冲区中的文件的大小,i是一个无符号整数。它不是在i == 0时停止,而是封装起来--从而导致i = 4294967295并导致分段错误。将条件更改为i > 0解决了这个问题。
不过,这不是很奇怪吗?我肯定缺少了for循环在C中运行的一些关键部分,它不遵循这个方案吗:初始化、检查条件、增量/减少、检查条件等等?
任何帮助都是非常感谢的!
发布于 2013-07-30 09:59:13
无符号整数总是>= 0。
for (i = size - 1; i >= 0; i--) {etc.}如果i是unsigned int,则为无限循环。
发布于 2013-07-30 10:13:08
让我们看看当i接近0时会发生什么。
i == 1:循环从i >= 0开始正常执行。从i中减去1。现在i包含0。i == 0:循环从i >= 0开始正常执行。从i中减去1。因为i没有签名,所以它会被环绕。因此,i现在包含4294967295。i == 4294967295:循环自i >= 0以来正常执行解决方案是要么测试其他东西(如i > 0,如您的示例),要么在每次迭代和循环时增加i,而它小于文件的大小。
发布于 2013-07-30 10:33:23
根据C99标准:
6.2.5类型 9) ..。涉及无符号操作数的计算永远不会溢出,因为不能用结果无符号整数类型表示的结果将被减少,即大于结果类型所能表示的最大值的数字。
所以,在你的案例中会发生什么:
i == 1,因此i--会导致i == 0。i == 0,因此,i--会产生一个环绕和i == UINT_MAX.i == UINT_MAX,因此i--会导致i == UINT_MAX - 1等等。修复循环的一种方法是使用以下方法(https://stackoverflow.com/a/665773/676939):
for (i = size; i-- > 0;){
/* yada yada yada */
}另一种同样的方法是以下(https://stackoverflow.com/a/665758/676939):
unsigned fake_i;
for (fake_i = size; fake_i > 0; i--){
unsigned i = fake_i - 1;
/* Do something with i */
}https://stackoverflow.com/questions/17943893
复制相似问题