c中处理scanf的分段错误

时间:2016-02-05 17:36:18

标签: c arrays segmentation-fault scanf

我正在编写一个程序,要求我做两个数组的联合。到目前为止,这是我的代码。 输入集A后,我将Segmentation fault作为错误。

#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了解得更多,所以我认为这与内存分配有关。我不太确定如何解决这个问题,所以如果你能指出我的方向会有所帮助。

3 个答案:

答案 0 :(得分: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只有20个元素。如果某些用户为N输入的值超过dataSource = new kendo.data.DataSource({ transport: { read: { url:"basedados.php", dataType: "json", }, parameterMap: function(options, operation) { return { access_token : "my_token" } } }, schema: { data: "data" } ,则阵列访问可能会超出范围。

答案 1 :(得分:1)

问题,我认为是在

scanf("%d",N );

scanf("%d",M );

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

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

您需要在那里传递地址,例如

scanf("%d", &N );

scanf("%d", &M );

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

答案 2 :(得分:0)

您收到细分错误的原因是您在阅读scanfN时调用M的方式。 %d的{​​{1}}格式说明符需要scanf,即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

修复这些问题,你应该得到理想的结果。