2014-02-25 99 views
0

我是C新手,無法繞過雙指針,並且不斷收到分段錯誤錯誤。我已經對程序進行了一些調試,找到了出錯的地方,但是不知道爲什麼。我首先發布我的代碼:使用雙指針的問題

int main() { 
    printf("Enter string to be split: \n"); 
    a = readline(); 
    String *st = newString(a); 
    String **split; 
    int num; 
    num = string_split(st, ',', split); 
    for (i=0; i<num; i++) { print_string(*(split+i)); } 
} 

的ReadLine()產生一個指向字符數組(由用戶輸入),並追加「\ 0」到它。 newString和print_string絕對有效。這裏是字符串的結構:

typedef struct { 
    char *chars; 
    int length; 
    int maxSize; 
} String; 

而這裏是string_split的代碼,這導致我所有這些麻煩。

int string_split(String *s, char delim, String **arrayOfStructs) { 
    char *c = getCharacters(s); 
    int len = length(s); 
    int begin = 0; 
    int end; 

    int arraycount = 0; 
    String **temp = (String**)malloc(sizeof(String*)); 

    for (end=0; end<len+1; end++) { 
     if ((*(c+end) == delim || *(c+end) == '\0') && begin != end) { 
      String *st = substring(s,begin,end-1); 
      *(temp + arraycount) = st; 
      begin = end + 1; 
      arraycount++; 
      temp = (String**)realloc(temp, 1+arraycount*sizeof(String*)); 
     } 
    } 

    arrayOfStructs = temp; 
    return arraycount; 
} 

主要是,當我重新分割時,它所指向的所有String *都消失了。當print_string獲取單個String *並嘗試抓取其中一個成員時,會發生分段錯誤。我不明白爲什麼,因爲我覺得每次都有必要分配內存,但是我覺得我錯過了一些東西。另外,在調試的時候,如果我通過string_split執行,temp的生成與我所期望的完全一致,所以我認爲我只是不是在某處應該處於什麼位置的malloc,而且它不是函數邏輯的問題。這裏是子字符串中的代碼,雖然我敢肯定它的工作原理,因爲我已經能夠從子字符串返回String *並將它們傳遞給print_string就好了。

String *substring(String *s1, int begin, int end) { 
    String *s = (String*)malloc(sizeof(String)); 
    int length = 0; 
    s->maxSize = 20; 
    char *temp = (char*)malloc(20*sizeof(char)); 
    char *arr = s1->chars; 

    int i; 
    for (i=begin; i <= end; i++) { 
     *(temp+length) = *(arr+i); 
     length++; 

     if (length == s1->maxSize-1) { 
      s1->maxSize = s1->maxSize+20; 
      temp = (char*)realloc(temp, s1->maxSize*sizeof(char)); 
     } 
    } 
    *(temp+length) = '\0'; 
    s->length = length; 
    s->chars = temp;  
    return s; 
} 

任何幫助,非常感謝!

回答

3

您需要通過引用傳遞參數arrayOfStructs而不是通過值。以C實際上並沒有正確的引用,必須將一個指針傳遞給變量:

int string_split(String *s, char delim, String ***arrayOfStructs) { 
    ... 

    *arrayOfStructs = temp; 
    return arraycount; 
} 

使用地址的運營商&稱之爲:

num = string_split(st, ',', &split); 

因爲它是現在,您通過值傳遞參數,這意味着變量arrayOfStructs只是函數內的本地副本。對其進行的任何更改僅針對該副本進行,並且在該函數返回時該變量超出範圍後會丟失。

+0

AHHHHH沒關係有意義我。如果我想把它作爲函數參數中的雙指針,我該怎麼辦?如果我malloced分裂主要會做伎倆? – user3344699

+0

@ user3344699是的,在函數外部分配會起作用,但是然後你無法在函數中重新分配它。 –

0
String **temp = (String**)malloc(sizeof(String*)); 

    *(temp + arraycount) = st; 

temp + arraycount會給你一個內存中的隨機地址。 temp包含你剛纔配對的指針,它應該指向另一個指針(你還沒有初始化),但是你正在增加指針,所以你鬆開了剛剛配置好的位置。

溫度不指向連續的存儲器,它具體地指向另一個指針(它是一個64位機器上8個字節)

+0

嗯...所以我應該malloc(temp + arraycount)而不是每次我想說*(temp + arraycount)= st?並且只聲明String ** temp;早?然後我不需要重新分配溫度? – user3344699

+0

@ user3344699你不能增加溫度。是的,你應該malloc * temp = malloc(你想要的大小)。你只能在你分配空間之後像這樣增加*(* temp)+ arraycount)。 – tesseract

+0

因爲我是C新手,所以我很可能會出錯,但是我能夠像你說的那樣提高溫度。我實施了Joachim Pileborg的建議,一切都奏效了。 – user3344699