簡體   English   中英

C 中的 function 運行一組值,但給出 Segmentation Fault: 11 for another

[英]A function in C runs for a set of values but gives Segmentation Fault: 11 for another

我試圖在兩組之間找到唯一的非零交集。 我已經編寫了一個適用於某些 arrays 的程序,但會出現一些分段錯誤。 我一直試圖找出原因但失敗了,任何幫助都將受到極大的重視。 問題是定義的函數(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);
}

再次感謝你的幫助!

看看這段代碼:

   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

但是您的代碼僅為CE1保留size_ar1 + size_ar2元素。 所以你最終可能會在數組之外寫。

通過在循環內打印cnt1可以很容易地看到這一點。

換句話說 - 你的CE1太小了。 它應該是:

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

但在這里要小心 - 如果輸入 arrays 很大,VLA 會變得很大,您可能會遇到堆棧溢出。 考慮動態 memory 分配而不是數組。

除了公認的答案:我在 ComEle function 的 while 循環中缺少一個 break 語句。 它沒有給我cnt1的預期值。 以下將是正確的方法:

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++;
            break;
         }
         j++;

      }

   }

這也將消除@4386427 建議(正確地)對更大數組或動態分配的要求

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM