编辑:最初我转录了
i++
而非i--
现在代码就是这样,代码块中的代码编译并运行。
为什么,如果在下面的代码段中使用unsigned int i;
代替int i;
,会在段错误中使用函数结果吗?
void insertion_sort_int_array(int * const Ints, unsigned int const len) {
unsigned int pos;
int key;
int i;
for (pos = 1; pos < len; ++pos) {
key = Ints[pos];
for (i = (pos - 1); (i >= 0) && Ints[i] > key; i--) {
Ints[i + 1] = Ints[i];
}
Ints[i + 1] = key;
}
}
答案 0 :(得分:2)
在任何一种情况下发布的代码都会失败(可能有段错误,可能只会破坏内存)。
内循环从pos-1开始并在内存中扫描向上,直到满足一些随机条件 - 它不检查它是否已经通过了数组的末尾,因此将快速运行直到它崩溃或者结束条件碰巧被它破坏的内存的(未定义的)内容所满足。
你可能打算在内存中扫描向下(在循环中使用i--),在这种情况下它会失败,因为循环将达到0.从0减去1给你一个非常大的无符号时的正数,所以循环永远不会结束(i> = 0总是为真),它将访问冥王星区域某处的某些内存。
答案 1 :(得分:2)
insertionSort(array A)
begin
for x := 1 to length[A]-1 do
begin
value := A[x];
i := x - 1;
while i >= 0 and A[i] > value do
begin
A[i + 1] := A[i];
i := i - 1;
end;
A[i + 1] := value;
end;
end;
标准插入排序算法与您的代码之间的唯一区别是您正在递增i而不是递减。那是你的问题。我敢打赌,在你实际编译和运行的代码中,你有i--而不是内循环中的i ++。这就是为什么无符号的i会产生影响 - 它不能为负,所以内部循环永远不会结束。您在发布时是否错误地复制了代码?
编辑:
好吧,既然你改变了发布的代码,那一切都有道理,对吧?当你将它递减到0时,无符号i将简单地下溢到INT_MAX,这将导致你访问数组边界之外的内存。
答案 2 :(得分:1)
什么使i + 1保持在数组“整数”的范围内?看起来数组中格式错误的数据会导致您索引到不应该存在的内存区域。
答案 3 :(得分:0)
i
将[环绕]导致访问超出数组限制
导入限制并与UINT_MAX
而不是之前的(i >= 0)
进行比较可解决问题:
#include <limits.h>
void insertion_sort_int_array(int * const Integers, unsigned int const N)
{
unsigned int o;
int target;
unsigned int i;
for (o = 1; o < N; o++) {
target = Integers[o];
for (i = (o - 1); (i != UINT_MAX) && (Ints[i] > target); i--) {
Integers[i + 1] = Integers[i];
}
Integers[i + 1] = key;
}
}
答案 4 :(得分:0)
为什么,如果unsigned int i;用来 而不是int i;在代码段中 下面,使用功能结果 在一个段错误?
因为对于unsigned int i
,i >= 0
始终为true,所以你的for循环不太可能在你想要的时候终止。
如果您的计数器未签名,则在向后循环(从高到低)时应始终非常小心。