2010-02-13 20 views
10

मैं समझ एक डबल सूचक को स्मृति आवंटित करने के लिए कैसे परेशानी हो रही हूँ। मैं तारों की एक सरणी पढ़ना चाहता हूं और इसे स्टोर करना चाहता हूं।स्मृति को डबल पॉइंटर पर असाइन करना?

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

बजाय इस बात का मैं सिर्फ स्मृति और दुकान स्ट्रिंग

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

की एक बड़ी ब्लॉक आवंटित है कि गलत हो सकता है? और यदि ऐसा है तो यह क्यों है?

+6

इसे "डबल पॉइंटर" न कहें - यह आपको मानसिक रूप से गलत पैर पर ले जाता है - यह एक सूचक के लिए सूचक है। –

उत्तर

0

एक डबल पॉइंटर एक और सूचक के लिए सिर्फ एक सूचक है। तो अगर आप इसे इस तरह आवंटित कर सकते हैं:

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

आप (समारोह रिटर्न के बाद तो यह अवैध है ढेर पर एक सूचक चर करने के लिए डबल सूचक अंक इस उदाहरण में) मन जहाँ आपके सूचक पर संग्रहीत किया जाता है में रखना है ।

-3

डबल पॉइंटर, बस एक पॉइंटर के लिए सूचक, कई मामलों में इसे अन्य प्रकारों की सरणी के रूप में उपयोग किया जाता है।

उदाहरण के लिए, आप तार की एक सरणी बनाना चाहते हैं तो आप बस कर सकते हैं:

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

इस आकार 10 की एक सरणी पैदा करेगा, प्रत्येक तत्व लंबाई के एक स्ट्रिंग होगा 40.

इस प्रकार आप स्ट्रिंगअरे [5] द्वारा इसका उपयोग कर सकते हैं और 6 वें स्थान पर एक स्ट्रिंग प्राप्त कर सकते हैं।

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

यहाँ और अधिक पढ़: good array tutorial

+0

नहीं, यह 100 char * की एक एकल सरणी बनाता है, मानते हुए char * 4 बाइट लेता है। –

+0

क्या हंस कहते हैं सही है। और भी, 100 char * की सरणी 0 से शुरू की गई है (चूंकि आपने कॉलोक का उपयोग किया था) इसलिए उन सभी char * शून्य को इंगित कर रहे हैं और उस सरणी स्थान तक पहुंचने से त्रुटि हो जाएगी। –

10

आपकी दूसरी उदाहरण है

इस

एक उपयोग, दूसरों के रूप में, जैसा कि ऊपर उल्लेख कर रहे हैं एक सूचक के लिए सूचक है, और बस आवंटित किया जा सकता है गलत क्योंकि प्रत्येक स्मृति स्थान अवधारणात्मक रूप से char* नहीं बल्कि char रखेगा। आप थोड़ा अपनी सोच बदलते हैं, तो यह इस के साथ मदद कर सकते हैं:

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' 
इस कारण से

, अपने पहले पाश होगा कि कैसे आप सी में चरित्र सरणियों/संकेत की एक सरणी है। वर्ण सरणी की सरणी के लिए स्मृति के एक निश्चित ब्लॉक का उपयोग करना ठीक है, लेकिन आप char** की बजाय एक char* का उपयोग करेंगे, क्योंकि आपके पास स्मृति में कोई पॉइंटर्स नहीं होगा, बस 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

अंतिम पंक्ति 'char * str = x + (ii * 50) 'नहीं होनी चाहिए? – redFur

+2

और 'malloc() 'के परिणाम कास्ट न करें! –

1

याद करने के लिए

केस -1 अन्य आसान तरीका:

कदम-1: चार * p;

कदम -2: कृपया इसे पसंद नीचे

चार (* पी) पढ़ा; ; ==> पी एक चार

अब

तुम सिर्फ प्रकार (चरण -2) ब्रेसिज़ के बिना के लिए malloc क्या करने की जरूरत

यानी, पी = malloc (sizeof (चार) * some_len) के लिए सूचक है

केस -2:

कदम-1: चार ** पी;

कदम -2:

कृपया इसे पसंद

नीचे

चार * (* पी) पढ़ा; ==> पी एक चार *

अब तुम सिर्फ प्रकार के लिए malloc क्या करने की जरूरत के लिए सूचक है (चरण -2) ब्रेसिज़ के बिना

यानी, पी = malloc (sizeof (चार *) * some_len) ;

केस -3:

कोई भी व्यक्ति इस का उपयोग करता है लेकिन सिर्फ स्पष्टीकरण की खातिर

चार के लिए *** पी;

इसे पढ़ें,

char ** (* p); ==> पी एक char के लिए एक सूचक है ** (और ऊपर इस चेक केस -2 के लिए)

पी = malloc (sizeof (char **) * some_len);

0

पेंट के उत्तर में जोड़कर, जैसा कि उसने सही ढंग से इंगित किया है, फ़ंक्शन लौटने के बाद आप इस डबल पॉइंटर का उपयोग नहीं कर पाएंगे, क्योंकि यह स्टैक पर फ़ंक्शन के सक्रियण रिकॉर्ड पर स्मृति स्थान को इंगित करेगा जो अब अप्रचलित है (एक बार समारोह वापस आ गया है)। आप समारोह के बाद वापस आ गया है इस डबल सूचक का उपयोग करना चाहते हैं, तो आप ऐसा कर सकते हैं:

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

समारोह की वापसी प्रकार स्पष्ट रूप से इस बात के लिए char ** होना चाहिए।

संबंधित मुद्दे