【问题标题】:Segmentation fault in c dealing with scanf处理scanf的c中的分段错误
【发布时间】:2016-02-05 17:36:17
【问题描述】:

我正在编写一个程序,要求我将两个数组合并。到目前为止,这是我的代码。 进入集合 A 后,我得到分段错误作为错误。

#include <stdio.h>

void Union(int a[], int b[], int set1, int set2)
{
    int u[20], i, j, unionIndex=0,trigger;

for(i=0; i<set1; i++)
{
    u[unionIndex] = a[i];
    unionIndex++;
}

for(i=0; i<set2; i++)
{
    trigger=0;
    for(j =0; j<set1; j++)
    {
        if(b[i] == u[j])
        {           
            trigger =1;
            break;
        }
    }
    if(trigger =0)
    {
        u[unionIndex]=b[i];
        unionIndex++;
    }
}

    for(i=0;i<unionIndex;unionIndex++)
    {
    printf(" %d",u[i]);
    }
}

   int main(void) {
   int N=0;
   int M=0;
   int i;
   int j;

   printf("Please enter the number of elements in set A: ");
   scanf("%d",N );
   int a[N];

   printf("Enter the numbers in set: ");
   for(i=0;i<N;i++)
   {
         scanf("%d",&a[i]);
   }

    printf("Please enter the number of elements in set B: ");
    scanf("%d",M );
    int b[M];

    printf("Enter the numbers in set: ");
    for(j=0;i<M;i++)
    {
         scanf("%d",&b[i]);
    }

    Union(a,b,N,M);
    return 0;
}

我很确定这个问题与数组有关,因为程序会编译,但在用户输入集合 A 后我立即得到错误。我是 C 的初学者,但我对 Java 了解更多,所以我认为这与内存分配有关。我不确定如何解决这个问题,所以如果你能指出我正确的方向,那会很有帮助。

【问题讨论】:

    标签: c arrays segmentation-fault scanf


    【解决方案1】:

    需要将变量的地址传递给scanf()

    改变

    printf("Please enter the number of elements in set A: ");
    scanf("%d",N );
    

    printf("Please enter the number of elements in set A: ");
    scanf("%d", &N);
    

    其他地方也一样

    printf("Please enter the number of elements in set B: ");
    scanf("%d", &M);
    

    还有一个可能的错误

    在这里

    for(j =0; j<set1; j++)
    {
        if(b[i] == u[j])
    

    在这个set1 等于N,所以j 将来自0 to N-1。而数组 u[] 只有 20 元素。如果某些用户为N 输入的值超过20,则数组访问可能会越界。

    【讨论】:

    • 这也是给M的。
    【解决方案2】:

    问题出在

    scanf("%d",N );
    

    scanf("%d",M );
    

    它调用undefined behavior,因为scanf() 需要将格式说明符的参数作为指向类型的指针。

    澄清一下,您实际上是将地址作为0(变量的值)传递,无论如何这不是有效的地址。

    你需要在那里传递地址,比如

    scanf("%d", &N );
    

    scanf("%d", &M );
    

    也就是说,在您的 Union() 函数中,您使用一个用户定义的值来限制 for 循环,而不是一个常量值 20。如果用户输入超过 20 个,您将超出调用 undefined behavior 的内存。

    【讨论】:

    • 哦,所以与内存分配无关?那我换个标题吧。谢谢。
    【解决方案3】:

    您遇到分段错误的原因是您在读取NM 时调用scanf 的方式。 scanf%d 格式说明符需要 int *,即 int 的地址,但您传入的是 int。这是未定义的行为。

    所以你可以像这样修复它们:

     scanf("%d",&N );
     ....
     scanf("%d",&M );
    

    一些额外的错误:

    循环读取b 的值时:

    for(j=0;i<M;i++)
    {
         scanf("%d",&b[i]);
    }
    

    你有错误的循环索引:

    for(j=0;j<M;j++)
    {
         scanf("%d",&b[j]);
    }
    

    查看trigger时:

    if(trigger =0)
    

    这是一个分配,而不是比较:

    if(trigger == 0)
    

    当循环打印出u:

    for(i=0;i<unionIndex;unionIndex++)
    

    你增加了错误的变量:

    for(i=0;i<unionIndex;i++)
    

    最后,u 至少需要有set1 + set2 的长度,否则你可能会在数组末尾写出:

    int u[set1+set2];
    

    解决这些问题,您应该会得到想要的结果。

    【讨论】:

      猜你喜欢
      • 2013-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多