2010-02-13 20 views
10

belleğinin çift işaretçiye nasıl atanacağını anlamakta güçlük çekiyorum. Bir dizi dizgeyi okumak ve saklamak istiyorum.Çift işaretçiye bellek atama?

char **ptr; 
    fp = fopen("file.txt","r"); 
    ptr = (char**)malloc(sizeof(char*)*50); 
    for(int i=0; i<20; i++) 
    { 
     ptr[i] = (char*)malloc(sizeof(char)*50); 
     fgets(ptr[i],50,fp); 
    } 

bunun yerine sadece o yanlış olur bellek ve mağazada dize

char **ptr; 
    ptr = (char**)malloc(sizeof(char)*50*50); 

büyük bir blok atamak? Ve eğer öyleyse neden?

+6

Buna "çift işaretçi" diyemezsiniz - bu yanlış zihninizi zihinsel olarak kapatır - işaretçinin işaretçisidir. –

cevap

0

Bir çift işaretçi, başka bir işaretçiye sadece bir işaretçi. Yani bunun gibi ayırabilirsiniz:

char *realptr=(char*)malloc(1234); 
char **ptr=&realptr; 

Sen (işlev döndükten sonra geçersiz yüzden yığınında bir işaretçi değişkene bu örnekte çift işaretçi noktaları) işaretçinizin saklanır akılda tutmak zorunda .

-3

Çift işaretçi, bir işaretçiye bir işaretçi koyulur, Çoğu durumda, başka türde bir dizi olarak kullanılır. Eğer dize dizisi oluşturmak istiyorsanız Örneğin

, sadece yapabilirsiniz: Bu büyüklükteki 10 bir dizi yaratacak

char** stringArray = calloc(10, 40); 

, her öğe uzunlukta bir dize olacaktır 40.

böylece stringArray [5] ile buna erişebilir ve 6. konumda bir dize alabilirsiniz.

char* str = (char*)malloc(40); 
char** pointerToPointer = &str //Get the address of the str pointer, valid only in the current closure. 

burada daha fazla okumak: good array tutorial

+0

Hayır, bu char * * 4 bayt alır varsayarak, 100 char * tek bir dizi oluşturur. –

+0

Hans'ın söylediği doğru. Dahası, 100 char * dizisi 0'a (calloc'u kullandığınızdan beri) başlatılır, böylece tüm bu char * null'a işaret eder ve bu dizi konumuna erişme bir hataya neden olur. –

10

Sizin ikinci örnektir

bu

bir kullanım, diğerleri bir işaretçi işaretçi, yukarıda değinildiği gibi, ve basitçe tahsis edilebilir olduğu Yanlış, her bellek konumu kavramsal olarak char*'u değil, bir char'u tutmaz. Eğer biraz düşüncen hiç değişmiyor ise, bu yardımcı olabilir:

nedenle
char *x; // Memory locations pointed to by x contain 'char' 
char **y; // Memory locations pointed to by y contain 'char*' 

x = (char*)malloc(sizeof(char) * 100); // 100 'char' 
y = (char**)malloc(sizeof(char*) * 100); // 100 'char*' 

// below is incorrect: 
y = (char**)malloc(sizeof(char) * 50 * 50); 
// 2500 'char' not 50 'char*' pointing to 50 'char' 

Eğer C karakter diziler/işaretçiler bir dizi nasıl, ilk döngü olacaktır. Bir dizi karakter dizisi için sabit bir bellek bloğu kullanmak tamam, ancak char** yerine bir char* kullanırsınız, çünkü belleğinizde herhangi bir işaretçiniz yoksa sadece char s.

char *x = calloc(50 * 50, sizeof(char)); 

for (ii = 0; ii < 50; ++ii) { 
    // Note that each string is just an OFFSET into the memory block 
    // You must be sensitive to this when using these 'strings' 
    char *str = &x[ii * 50]; 
} 
+1

son satır "char * str = x + (ii * 50)' olmalıdır değil mi? – redFur

+2

Ve 'malloc()' sonucunu vermeyin! –

1

Örneği -1 ezberlemek diğer daha basit bir şekilde:

adım 1 char * p;

adım -2:

altında char (* p) gibi okuyun; ; ==> p sadece parantez olmayan tip (adım 2) için Malloc yapmak gerekir

yani, p = Malloc (sizeof (char) * some_len) char hemen

bir işaretçidir

Örnek -2:

adım 1 char ** p;

adım -2:

altında char * (* p) gibi okuyun; ==> p

şimdi sadece türü için malloc yapmanız gereken * bir char bir göstericidir (adım-2) parantez olmadan

yani p = malloc (sizeof (char, *) * some_len) ;

Vaka -3:

Hiç kimse bunu kullanır ama sadece açıklama uğruna

karakter için *** p;

char ** (* p) olarak okuma; ==> p, bir char ** 'nin bir işaretçisidir (ve bu kontrol durumu-2 için)

p = malloc (sizeof (char **) * some_len);

0

Doğru bir şekilde işaret ettiği gibi, Pentium'un yanıtına eklendiğinde, işlev döndükten sonra bu ikili işaretçiyi kullanamazsınız, çünkü artık işlevsiz olan yığındaki işlevin aktivasyon kaydındaki bir bellek konumuna işaret edecektir (işlev döndüğünde). Eğer işlevi döndürdü sonra bu çifte işaretçi kullanmak istiyorsanız, bunu yapabilirsiniz:

char * realptr = (char *) malloc(1234); 
char ** ptr = (char **) malloc(sizeof(char *)); 
*ptr = realptr; 
return ptr; 

fonksiyonun dönüş tipi Açıkçası bunun için char ** olmalıdır.