对 unsigned int 执行算术运算后出现分段错误
Getting segmentation fault after performing arithmetic on unsigned int
代码如下。我遇到分段错误不明白为什么。我认为这是因为我对变量 t 和 k(都是 unsigned int)做的算术运算,谁能解释为什么会出现这个分段错误。
#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;
}
我认为问题与这个 if 语句有关
if(t-k>0)
printf("%u\n",a[t-k]);
因为 t
和 k
都是无符号整数,所以 t-k
的结果总是非负的,即使 t
小于 k
.但是结果可以给数组元素a[t-k]
一个wong索引
else 语句
else
printf("%u\n",a[t-k+n]);
仅在 t
等于 k
时执行:) 但在这种情况下,数组 t-k+n
的索引将等于 n 并引用数组后面.
printf("%u\n",a[t-k+n]);
考虑到 if 语句中的条件
if(t-k>0)
可以代替
if ( t > k )
但是无论如何你应该检查输出元素的结果索引是否有效。
由于代码很小,这可能是开始使用 gdb 的好机会。这样,您可以节省很多时间。这是一个 introductory tutorial.
问题出在这里:
if(t-k>0) // <- HERE!
printf("%u\n",a[t-k]);
else
printf("%u\n",a[t-k+n]);
因为 t
和 k
是无符号整数。这些变量的某些值将暴露问题。例如,我在 if-else 语句之前添加了一个 printf()
,我得到:
2
2
2
1
2
1
RESULT: -1
Segmentation fault (core dumped)
所以,你可以看到,因为变量是无符号整数,所以t-k
的结果是always非-负数,作为无符号整数运算的结果,无论 t
和 k
的值是什么。
作为解决方案,您可以将这两个变量设置为整数,如下所示:
#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。
代码如下。我遇到分段错误不明白为什么。我认为这是因为我对变量 t 和 k(都是 unsigned int)做的算术运算,谁能解释为什么会出现这个分段错误。
#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;
}
我认为问题与这个 if 语句有关
if(t-k>0)
printf("%u\n",a[t-k]);
因为 t
和 k
都是无符号整数,所以 t-k
的结果总是非负的,即使 t
小于 k
.但是结果可以给数组元素a[t-k]
else 语句
else
printf("%u\n",a[t-k+n]);
仅在 t
等于 k
时执行:) 但在这种情况下,数组 t-k+n
的索引将等于 n 并引用数组后面.
printf("%u\n",a[t-k+n]);
考虑到 if 语句中的条件
if(t-k>0)
可以代替
if ( t > k )
但是无论如何你应该检查输出元素的结果索引是否有效。
由于代码很小,这可能是开始使用 gdb 的好机会。这样,您可以节省很多时间。这是一个 introductory tutorial.
问题出在这里:
if(t-k>0) // <- HERE!
printf("%u\n",a[t-k]);
else
printf("%u\n",a[t-k+n]);
因为 t
和 k
是无符号整数。这些变量的某些值将暴露问题。例如,我在 if-else 语句之前添加了一个 printf()
,我得到:
2
2
2
1
2
1
RESULT: -1
Segmentation fault (core dumped)
所以,你可以看到,因为变量是无符号整数,所以t-k
的结果是always非-负数,作为无符号整数运算的结果,无论 t
和 k
的值是什么。
作为解决方案,您可以将这两个变量设置为整数,如下所示:
#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。