2009-08-29 15 views
31

के सदस्य के रूप में फ़ंक्शन पॉइंटर मेरे पास एक संरचना है जो "लम्बाई" नामक फ़ंक्शन के पॉइंटर के साथ होती है जो वर्ण सदस्य की लंबाई वापस कर देगी।)सी संरचना

int length(PString * self) { 
    return strlen(self->chars); 
} 

मैं एक समारोह initializeString है (कि एक PString के लिए सूचक रिटर्न:

typedef struct pstring_t { 
    char * chars; 
    int (* length)(); 
} PString; 

मैं एक PString के लिए सूचक से वर्णों की लंबाई वापस जाने के लिए एक समारोह है

PString * initializeString() { 
    PString *str; 
    str->length = &length; 
    return str; 
} 

यह स्पष्ट है कि मैं अपने पॉइंटर्स के साथ कुछ गलत कर रहा हूं, क्योंकि str->length = &length लाइन मेरे डीबगर में EXC_BAD_ACCESS सिग्नल का कारण बनती है, जैसा कि 'वापसी स्ट्रेल (स्वयं-> char रों)। क्या किसी को इस समस्या में कोई अंतर्दृष्टि है?

मैं विशेष रूप से प्रारंभ करना चाहता हूं प्रारंभिक स्ट्रिंग() फ़ंक्शन एक पॉइंटर को एक पॉइंटर लौटाता है, और लम्बाई फ़ंक्शन को इनपुट के रूप में एक पीएसटीआरिंग में पॉइंटर का उपयोग करने के लिए करता है। यह सी में प्राथमिक वस्तु-उन्मुख प्रणाली को लागू करने में केवल एक प्रयोग है, लेकिन मेरे पास पॉइंटर्स हेड-ऑन से निपटने का बहुत अधिक अनुभव नहीं है। किसी भी सहायता के लिए धन्यवाद जो आप मुझे दे सकते हैं।

+2

यद्यपि आप कहते हैं कि आप विशेष रूप से एक सूचक वापस जाने के लिए चाहते हैं। इस मामले में, एक संरचना खुद को वापस करना बेहतर है। यह प्रतिलिपि बनाने के लिए एक सस्ता है, और भारी वजन ढेर आवंटन की कोई आवश्यकता नहीं है। स्ट्रिंग ऑब्जेक्ट्स मूल्य-आधारित हैं: उनके पास पहचान (पता) नहीं है, लेकिन उनकी समानता उनकी सामग्री पर आधारित है। आप किसी भी तरह, अपने ओओपी सिस्टम में भी भेदभाव की भावना हो सकती है। –

उत्तर

48

वर्ण रखने के लिए स्मृति आवंटित करें।

#include <stdio.h> 
#include <stdlib.h> 

typedef struct PString { 
     char *chars; 
     int (*length)(); 
} PString; 

int length(PString *self) { 
    return strlen(self->chars); 
} 

PString *initializeString(int n) { 
    PString *str = malloc(sizeof(PString)); 

    str->chars = malloc(sizeof(char) * n); 
    str->length = length; 

    str[0] = '\0'; //add a null terminator in case the string is used before any other initialization. 

    return str; 
} 

int main() { 
    PString *p = initializeString(30); 
    strcpy(p->chars, "Hello"); 
    printf("\n%d", p->length(p)); 
    return 0; 
} 
+0

महान जवाब! प्रश्न: मुझे मुफ्त (पी) कॉल करने की आवश्यकता है, लेकिन क्या मुझे वर्णों को मुक्त करने की भी आवश्यकता है? –

+0

मुझे लगता है कि मुझे एक विनाशक लिखने की जरूरत है। –

+12

सी में 'malloc' के वापसी मूल्य को डालने की कोई आवश्यकता नहीं है। इसके अलावा, आपको इसे आवंटित करने के बाद' str-> वर्ण 'प्रारंभ करना चाहिए (यानी' str-> वर्ण [0] = '\ 0'; ') । – caf

4

सूचक str कभी आवंटित नहीं किया जाता है। उपयोग से पहले malloc 'डी होना चाहिए।

+0

'PString * str = (PString *) malloc (sizeof (PString)) के साथ 'PString * str;' बदलें;' और आदर्श रूप से, स्मृति लीक से बचने के लिए इसका उपयोग करते समय पॉइंटर के साथ 'फ्री' को कॉल करें। – jgottula

6

मेरा अनुमान है कि आपकी समस्या का हिस्सा पैरामीटर सूचियों से मेल नहीं खाता है।

int (* length)(); 

और

int length(PString * self) 

ही नहीं हैं। यह int (* length)(PString *); होना चाहिए।

... वाह, यह जॉन है!

संपादित करें: और जैसा कि नीचे बताया गया है, आपका स्ट्रक्चर पॉइंटर कभी भी कुछ भी इंगित करने के लिए सेट नहीं है। जिस तरह से आप इसे कर रहे हैं वह केवल तभी काम करेगा जब आप एक सादा संरचना घोषित कर रहे हों, न कि सूचक।

str = (PString *)malloc(sizeof(PString)); 
+0

बहुत बहुत धन्यवाद, जैकब। मैं आगे बढ़ जाऊंगा और कोशिश करूँगा। –

+0

ठीक है, 'strlen (self-> वर्ण)' अभी भी मुझे 'EXC_BAD_ACCESS' देता है। –

4

शायद मुझे यहां कुछ याद आ रही है, लेकिन क्या आपने इसे एक्सेस करने से पहले उस PString के लिए कोई स्मृति आवंटित की थी?

PString * initializeString() { 
    PString *str; 
    str = (PString *) malloc(sizeof(PString)); 
    str->length = &length; 
    return str; 
} 
0

आप फ़ंक्शन में पता भेजने के लिए "शून्य *" (शून्य सूचक) का भी उपयोग कर सकते हैं।

typedef struct pstring_t { 
    char * chars; 
    int(*length)(void*); 
} PString; 

int length(void* self) { 
    return strlen(((PString*)self)->chars); 
} 

PString initializeString() { 
    PString str; 
    str.length = &length; 
    return str; 
} 

int main() 
{ 
    PString p = initializeString(); 

    p.chars = "Hello"; 

    printf("Length: %i\n", p.length(&p)); 

    return 0; 
} 

आउटपुट:

Length: 5 
संबंधित मुद्दे