首页 > 解决方案 > C 中的函数针对一组值运行,但给出 Segmentation Fault: 11 for another

问题描述

我试图在两组之间找到唯一的非零交集。我编写了一个适用于某些数组集的程序,但会导致某些数组出现分段错误。我一直试图找出原因但失败了,任何帮助都将受到极大的重视。问题是定义的函数(NoRep 和 ComEle)工作正常,但在显示 Seg Fault 的情况下无法将值返回给分配的指针。下面是代码:

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


int* ComEle(int ar_1[], int size_ar1, int ar_2[], int size_ar2);
int* NoRep(int a[], int l1);

int main ()

{
   // Case 1: Gives segmentation fault
   int A[10] = {1,1,0,2,2,0,1,1,1,0};
   int B[10] = {1,1,1,1,0,1,1,0,4,0};
   int *C = ComEle(A,10,B,10); printf("check complete\n");


   // //Case 2: Does not give segmentation fault
   // int A[4] = {2,3,4,5};
   // int B[4] = {1,2,3,4};
   // int *C = ComEle(A,4,B,4); printf("check complete\n");


}


//---------------- Local Functions --------------------//

int* ComEle(int ar_1[], int size_ar1, int ar_2[], int size_ar2) {

// sort of intersection of two arrays but only for nonzero elements.

   int i=0, j=0, cnt1 = 0;
   int temp1 = size_ar1+size_ar2;
   int CE1[temp1]; for(i=0;i<temp1;i++) {CE1[i] = 0;}
   /* Size of CE1 is knowingly made big enough to accommodate repeating
      common elements which can expand the size of resultant array to
      values bigger than those for the individual arrays themselves! */

   for(i=0;i<size_ar1;i++) {
      j = 0;
      while(j<size_ar2) {
         if(ar_1[i]==ar_2[j] && ar_1[i]!=0) {
            CE1[cnt1] = ar_1[i];
            cnt1++;          
         }
         j++;
      }

   }
// Have to remove repeating elements.   

   int *CE = NoRep(CE1, cnt1);
   for(i=0;i<(CE[0]+1);i++) {printf("CE:\t%d\n", CE[i]);}
   printf("ComEle: %p\n",CE);
return(CE);
}

int* NoRep(int a[], int l1) {

   int cnt = 0, i = 0, j =0;
   int *NR; NR = (int*)calloc((l1), sizeof(int));
   //int NR[l1]; for(i=0;i<l1;i++) {NR[i] = 0;}
   for(i=0;i<l1;i++) {
      j = 0;
      while(j<i) {
         if(a[i]==a[j]) {break;}
      j++;
      }
      if(j == i) {
         cnt++;
         NR[cnt] = a[i];         
      }

   }

   NR[0] = cnt;  // First element: # of relevant elements.
   printf("NoRep: %p\n",NR);

return(NR);
}

再次感谢您的帮助!

标签: carrayspointerssegmentation-faultfunction-pointers

解决方案


看看这段代码:

   int temp1 = size_ar1+size_ar2;
   int CE1[temp1]; for(i=0;i<temp1;i++) {CE1[i] = 0;}
   /* Size of CE1 is knowingly made big enough to accommodate repeating
      common elements which can expand the size of resultant array to
      values bigger than those for the individual arrays themselves! */

   for(i=0;i<size_ar1;i++) {
      j = 0;
      while(j<size_ar2) {
         if(ar_1[i]==ar_2[j] && ar_1[i]!=0) {
            CE1[cnt1] = ar_1[i];
            cnt1++;          
         }
         j++;
      }
   }

在这里,您有嵌套循环,即内部带有while 循环的for 循环。所以 - 在最坏的情况下 - 可以cnt1增加多少次?

答案是size_ar1 * size_ar2

但是您的代码仅保留size_ar1 + size_ar2元素为CE1. 所以你最终可能会在数组之外写。

cnt1通过在循环内打印,您可以很容易地看到这一点。

换句话说 - 你CE1的太小了。它应该是:

   int temp1 = size_ar1*size_ar2;  // NOTICE: * instead of +
   int CE1[temp1]; for(i=0;i<temp1;i++) {CE1[i] = 0;}

但是在这里要小心——如果输入数组很大,VLA 会变得很大,你可能会遇到堆栈溢出。考虑动态内存分配而不是数组。


推荐阅读