使用另一个数组为数组编制索引-gcc 6.3运行时错误
我读了一个关于导致运行时错误的代码的问题,例如seg错误 我试图用ideone.com调试代码,结果很奇怪 我已将代码精简到最低版本,以重现这种奇怪的行为。因此,代码没有做任何有意义的事情。代码的目的只是显示奇怪的行为 代码示例1: 看 使用的编译器是GCC 6.3 区别只是:使用另一个数组为数组编制索引-gcc 6.3运行时错误,c,gcc,language-lawyer,C,Gcc,Language Lawyer,我读了一个关于导致运行时错误的代码的问题,例如seg错误 我试图用ideone.com调试代码,结果很奇怪 我已将代码精简到最低版本,以重现这种奇怪的行为。因此,代码没有做任何有意义的事情。代码的目的只是显示奇怪的行为 代码示例1: 看 使用的编译器是GCC 6.3 区别只是: .... a[s[r]] .... in example 1 及 所以问题是为什么第一个示例失败,第二个示例执行良好 我在代码中查找了UB,但找不到任何UB。代码中有UB吗 这是GCC 6.3中已知的错误吗 更新 正如
.... a[s[r]] .... in example 1
及
所以问题是为什么第一个示例失败,第二个示例执行良好
我在代码中查找了UB,但找不到任何UB。代码中有UB吗
这是GCC 6.3中已知的错误吗
更新
正如Scott Hunter正确指出的,这两个代码示例所做的并不相同
第一个示例由于UB而失败,因为变量r在while主体内变为-1,并且在while的下一个条件检查中,它访问s[-1]。例如,在两个版本中,r在while循环中发生变化;因此,在第一个版本中,与a[i]进行比较的a元素的索引发生变化,但在第二个版本中不发生变化。在两个版本中,r在while循环中发生变化;因此,在第一个版本中,与a[i]进行比较的a元素的索引会发生变化,但在第二个版本中不会发生变化。问题在于,在循环中,r变为-1。这就解释了。问题是r在循环中变成了-1。这就解释了。下次你想问一些小改动,你应该事先区分两个版本。下次你想问一些小改动,你应该事先区分两个版本。
#include <stdio.h>
int main() {
int a[3] = {3, 2, 5};
int s[3] = {0, 0, 0};
int r = 0;
int i;
for(i = 1; i < 3; i++) {
int t = s[r]; // These 2 lines
while((a[i] < a[t]) && (r >= 0)) //
// while((a[i] < a[s[r]]) && (r >= 0)) // instead of this line
{
r--;
}
printf("initialize s[%d] to %d\n", r+1, i);
++r;
s[r] = i;
}
printf("%d\n", r);
return 0;
}
initialize s[0] to 1
initialize s[1] to 2
1
.... a[s[r]] .... in example 1
int t = s[r]; in example 2
.... a[t] ....