2012-11-11 26 views
7

在PROGRAMM開始時,我分配內存炭指針數組:用C排序:交換指針導致意想不到的結果

char **buffer = calloc(20, sizeof(char *));

然後,用戶可以輸入最多20個字:我想對這個數組進行排序。它的工作原理,如果我用我的交換功能如下預期:

void swap(char *args1, char *args2) { 
    char tmp[40]; 
    strcpy(tmp, args1); 
    strcpy(args1, args2); 
    strcpy(args2, tmp); 
} 

void sort(char **args, int count) { 
    ... 
    swap(args[i], args[j]); 
    ... 
} 

通過這個思前想後,我發現,這是因爲我不得不這樣做實際上是重定向指向相應的字符串CPU的浪費。 所以我改寫了我的交換功能:

void swap(char **args1, char **args2) { 
    char *tmp = *args1; 
    *args1 = *args2; 
    *args2 = tmp; 
} 

void sort(char **args, int count) { 
    ... 
    swap(&args[i], &args[j]); 
    ... 
} 

然而,這不會在所有的工作,結果非常意外,我想不通爲什麼(我試了幾個電話的printf和諸如此類的東西)......我的理解是該指針只是重定向,從而交換,比方說,記憶是這樣的:

(begin of char**): 
100: *160 
108: *200 
116: *240 
124: *280 
... 
(begin of char*): 
160: Hello!\0 
200: World!\0 
... 

我的想法是改變指針而不是數組的最小CPU工作(這裏:具有指針交換指針100 108):

(begin of char**): 
100: *200 
108: *160 
116: *240 
124: *280 
... 
(begin of char*): 
160: Hello!\0 
200: World!\0 
... 

我試圖儘可能詳細地解釋這一點,如果太多解釋我很抱歉。 如果有人能給我洞察和幫助,我會很高興!

完整的代碼(與工作的strcpy)可以在這裏找到:http://pastie.org/5361481

+0

對於非工作代碼的完整代碼如何? –

+0

非工作代碼只是替換掉的交換方法和調用:http://pastie.org/5361515 – Danyel

+1

嘗試通過調試器逐行執行代碼(對於一小組輸入當然)。 –

回答

5

你的排序功能應該結束這樣看:

void sort(char ** args, const int start, const int end) { 
     char **pivot = &args[end]; 
     int i = start-1, j = start; 
     while(j < end) { 
       int cmp = strcmp(*pivot, args[j]); 
       if(cmp > 0) 
         swap(&args[++i], &args[j]); 
       j++; 
     } 
     swap(&args[++i], pivot); 
     if(start + 1 < i) 
       sort(args, start, i - 1); 
     if(end - 1 > i) 
       sort(args, i + 1, end); 
} 

我懷疑你沒有做樞軸成爲char**,但將其保留爲char*。如果你這樣做了,那麼每當你進行交換時,你實際上並沒有交換數組中的兩個元素,而是用一個局部變量交換數組中的一個元素。 pivot變量最終指向一個不同的字符串,而不是指向另一個字符串的最後一個數組成員。

+0

這解決了這個問題,但我不明白爲什麼我必須使樞軸成爲'char **'而不是'char *' – Danyel

+0

@Danyel:我試圖解釋得更好一點。讓我知道如果它仍然不清楚。 –

+0

哦,我想我明白了。 :)是的,它是有道理的,但我不得不重新考慮它,因爲在想了這麼多我的頭開始疼。 :D – Danyel

3
char *pivot = args[end]; 
... 
    swap(&args[++i], &pivot); 

這是你的問題。你不想用你的局部變量交換指針,而是用數組中的實際元素(這將是args+end)。 working example here

+0

謝謝,別人也解決了它。這是確切的問題! :) – Danyel