2014-12-02 60 views
0

下面是一個程序,該程序根據特定規則生成諸如「aaabaabaaa」(或只是空字符串)的單詞,一切工作正常,它生成它,大小,然後按字母順序,但當我實施部分,防止產生相同的詞它給了我「分段錯誤(核心轉儲)」C中的分段錯誤(生成字符串,當我檢查重複項時發生錯誤)

我的問題是什麼導致它,我該如何解決它?

(我用用gcc compliler在Ubuntu 14.04的代碼::塊)

整個程序

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

void bsas(int n, char **words); 

void as(int n, char **words) { 
     int rn = rand(); 
     strcat(words[n], "a"); 
     if(rn % 3 == 0) as(n, words); 
     if(rn % 3 == 1) bsas(n, words); 
} 

void bsas(int n, char** words){ 
     int rn, j; 
     for(j=0; j<2; j++){ 
       if(j == 0) 
         strcat(words[n], "b"); 
       else 
         strcat(words[n], "a"); 
       rn = rand(); 
       if(rn % 3 == 0) as(n, words); 
       if(rn % 3 == 1) bsas(n, words); 
     } 
} 

static int compareCombo(const void * a, const void * b){ 
     if (strlen(*(const char **) a) < strlen(*(const char **) b)) 
       return -1; 
     else if (strlen(*(const char **) a) > strlen(*(const char **) b)) 
       return 1; 
     else 
       return strcmp (*(const char **) a, *(const char **) b); 
} 

int main() 
{ 
     int rnum = 0, i, j, n; 
     char** words; 
     srand(time(NULL)); 
     system("clear"); 
     printf("\n Opis gramatyki: \n S->aS|bSaS|ε \n"); 
     getchar(); 
     printf("Ile chesz wygenerowac lancuchow? "); /*means how much words do you want to generate*/ 
     scanf("%d", &n); 
     words = (char**) malloc(n*sizeof(char*)); 
     for (i = 0; i < n; i++) 
     { 
       words[i] = (char*) malloc(40000*sizeof(char)); 
     } 

     for(i=0; i<n; i++){ 
       rnum = rand(); 
       if(rnum % 3 == 0) as(i, words); 
       if(rnum % 3 == 1) bsas(i, words); 
       if(rnum % 3 == 2) ; 
       /*:PROBLEM OCCURS when I add this: */ 
       **for(j = i-1; j >= 0; j--){ 
         if(strcmp(words[i], words[j]) == 0){ 
           words[i] = ""; 
           i--; 
           break; 
         } 
       }** 
       /* 
        this should check if there are some duplicates among words 
        if there are any it should erase it, and try to generate it again 
       */ 
     } 
     qsort (words, n, sizeof (const char *), compareCombo); 
     for(i = 0; i < n; i++){ 
       printf("%d\t- %s\n", i+1, words[i]); 
     } 
     return 0; 
} 

出現錯誤時,該節:我回答你

/*:PROBLEM OCCURS when I add this: */ 
      for(j = i-1; j >= 0; j--){ 
       if(strcmp(words[i], words[j]) == 0){ 
        words[i] = ""; 
        i--; 
        break; 
       } 
      } 
      /* 
      this should check if there are some duplicates among words 
      if there are any it should erase it, and try to generate it again 
      */ 

回答

3

在第一在第一次迭代時訪問字[-1],但後來看到您檢查j> = 0 .. 我對您的代碼有2條評論:分配後有 每個單詞,請清除你的緩衝區 - 因爲你追捕這個詞可能會導致意外的行爲和內存損壞。 不要用單詞[i] =「」清除重複的單詞;使用方法:

strcpy(words[i],""); 

這樣你是不是失去了以前由詞所指向的分配的緩衝區[I]

3

實際上有在代碼中的兩個錯誤。

if(rnum % 3 == 2) ;將使word[i]未初始化。那麼你只能希望你分配的40000個字節中的一個是零。很可能緩衝區中會有一個零,但如果不是,則strcmp將超過緩衝區的末尾,導致未定義的行爲。

第二個問題是,那將指針替換讀/寫緩衝器中的40000字節,一個指針到一個字節只讀緩衝行

words[i] = ""; 

。當您隨後嘗試使用asbsas函數寫入該緩衝區時,將會出現分段錯誤。糾正問題的一種方法是使用下面的行以清除字

words[i][0] = '\0'; 

但實際上,你並不需要在所有清除的話,因爲緩衝區是未初始化反正,和你是遞減i從列表中刪除該單詞。