在对unsigned int执行算术后获得分段错误

时间:2015-08-17 10:00:00

标签: c segmentation-fault unsigned-integer integer-arithmetic

代码如下。我得到分段错误无法理解原因。我认为这是因为我对变量t和k进行了算术运算(两者都是无符号整数),任何人都可以解释为什么会出现这种分段错误。

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int main() {

    unsigned int n,k,q,i,t;
    scanf("%u %u %u",&n,&k,&q);
    unsigned int a[n];
    for(i=0;i<n;i++)
    {
        scanf("%u",&a[i]);
    }
    for(i=0;i<q;i++)
    {
        scanf("%u",&t);
        if(t-k>0)
            printf("%u\n",a[t-k]);
        else
            printf("%u\n",a[t-k+n]);
    }   
    return 0;
}

2 个答案:

答案 0 :(得分:4)

我认为问题与此if语句

有关
    if(t-k>0)
        printf("%u\n",a[t-k]);

由于tk都是无符号整数,因此即使t-k小于tk的结果也始终为非负数。但结果可以为数组元素a[t-k]

提供一个wong索引

其他声明

    else
        printf("%u\n",a[t-k+n]);

仅在t等于k时执行。:)但在这种情况下,数组t-k+n的索引将等于n并且引用​​beyind数组。< / p>

printf("%u\n",a[t-k+n]);

考虑if语句中的condotion

if(t-k>0)

可以替代

if ( t > k )

但无论如何你应该检查输出元素的结果索引是否有效。

答案 1 :(得分:3)

由于代码很小,这可能是开始使用 gdb 的好机会。这样,你可以节省很多时间。这是一个introductory tutorial

问题在于:

if(t-k>0) // <- HERE!
  printf("%u\n",a[t-k]);
else
  printf("%u\n",a[t-k+n]);

因为tk是无符号整数。这些变量的某些值会暴露出这个问题。例如,我在if-else语句之前添加了printf(),然后我得到了:

2
2
2
1
2
1
RESULT: -1
Segmentation fault (core dumped)

所以,你可以看到,因为变量是无符号整数,t-k的结果是 始终 非负,作为操作的结果无符号整数,无论​​tk的值是多少。

作为解决方案,您可以将这两个变量设置为整数,如下所示:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int main() {

    unsigned int n,q,i;
    int t,k;
    scanf("%u %d %u",&n,&k,&q);
    unsigned int a[n];
    for(i=0;i<n;i++)
    {
        scanf("%u",&a[i]);
    }
    for(i=0;i<q;i++)
    {
        scanf("%d",&t);
        printf("RESULT: %d\n", t-k);
        if(t-k>0)
            printf("%u\n",a[t-k]);
        else
            printf("%u\n",a[t-k+n]);
    }   
    return 0;
}

现在输出变为:

2
2
2
1
2
1
RESULT: -1
2

可以看出,此处没有发生分段错误,2按预期打印。

相关问题