2012-11-11 6 views
7

yol açar, Char-işaretçiler bir dizi için bellek tahsis:C Sınıflandırma: işaretçiler pompalanması beklenmedik sonuçların programm başlangıcında

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

Sonra kullanıcı girebilir 20 kelime kadar:

buffer[i] = calloc(40, sizeof(char)); 
fgets(buffer[i], 40, stdin)` 

Daha sonra bu diziyi sıralamak istiyorum.

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]); 
    ... 
} 

bu sayede düşünme sonra bu aslında tekabül eden dizeleri işaretçiler yönlendirme edildi yapmak zorunda olduğunu çünkü CPU kaybı bulunduğunu fark etti: Bu aşağıdaki gibi benim takas işlevini kullanın, beklendiği gibi çalışır.

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

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

Ancak bu ... Benim anlayış oldu (Birkaç printf aramaları ve etajer denedik) neden çözemiyorum, sonuçları son derece beklenmedik, hiç çalışmaz: Yani benim takas işlevini yeniden yazdı işaretçileri sadece yönlendirildi ve böylece takas olduğunu, bellek şöyle diyelim: pointer ile 100'de takas işaretçisi: Benim fikrim yerine İşte asgari CPU çaba (için dizilerin işaretçileri değiştirmeye oldu

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

108):

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

Bunu olabildiğince ayrıntılı olarak açıklamaya çalıştım ve çok fazla açıklama varsa özür dilerim. Birisi bana bu konuda fikir verebilir ve yardım ederse çok sevinirim!

(çalışma strcpy ile) tam kod burada bulunabilir: http://pastie.org/5361481

+0

Çalışmayan kodun tam koduna ne dersiniz? –

+0

Çalışmayan kod yalnızca değiştirilen takas yöntemiyle ve aramalarla ilgilidir: http://pastie.org/5361515 – Danyel

+1

Kod boyunca satır satır adım, bir hata ayıklayıcısını deneyin (küçük bir girdi grubu için). –

cevap

5

Sizin sıralama işlevi bu benzeyen sonunda olmalıdır:

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); 
} 

Sana pivotu yapmadığını şüpheli char** olun, ancak char* olarak bırakın. Bunu yaparsanız, takas işlemini gerçekleştirdiğinizde, dizinizdeki iki öğeyi gerçekten değiştirmezsiniz, ancak dizinin bir öğesini yerel bir değişkenle değiştirmezsiniz. Pivot değişken, farklı bir dizgiyi işaret eden son dizi elemanı yerine farklı bir dizgiyi işaret ederek biter.

+0

Bu problemi çözdü ama neden anlamıyorum anlamıyorum bir char * 'yerine char' '' char * ' – Danyel

+0

@Danyel: Biraz daha iyi açıklamaya çalıştım. Hala açık değilse bana bildirin. –

+0

Ohh, sanırım anladım. :) Evet, mantıklı ama tekrar düşünmem gerekiyor çünkü çok düşündükten sonra başım ağrıyor. : D – Danyel

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

Bu sizin sorununuz. İşaretçiyi yerel değişkeninizle değiştirmek istemezsiniz, ancak dizideki gerçek pivot elemanı ile (args+end olur). working example here

+0

Teşekkürler, başka biri de çözdü. Tam problem buydu! :) – Danyel