2010-08-11 13 views
9

"केविन" प्रिंट करने के लिए अपेक्षित कोड के नीचे, लेकिन यह कचरा मूल्य प्रिंट कर रहा है। मैंने डीबगर में चेक किया है। "ऑपरेटर char *" कॉल द्वारा लौटा गया सूचक अमान्य है। कोई उपाय?"ऑपरेटर char *" मुद्दा

class Wrapper 
{ 
private: 
    char* _data; 

public: 

    Wrapper(const char* input) 
    { 
     int length = strlen(input) + 1; 
     _data = new char[length]; 
     strcpy_s(_data, length, input); 
    } 

    ~Wrapper() 
    { 
     delete[] _data; 
    } 

    operator char*() 
    { 
     return _data; 
    } 
}; 

int main() 
{ 
    char* username = Wrapper("kevin"); 
    printf(username); 
    return 0; 
} 
+6

मेरा पहला सुझाव केवल std :: स्ट्रिंग का उपयोग करना होगा क्योंकि आप स्पष्ट रूप से C++ का उपयोग कर रहे हैं। –

+0

आपने जो पॉइंटर्स टैग जोड़ा है, उसे आपने क्यों संपादित किया? – James

+0

ध्यान रखें कि आपको आम तौर पर निहित रूपांतरणों से बचना चाहिए। (और निश्चित रूप से, 'std :: vector', या 'std :: string', आदि का उपयोग करें) – GManNickG

उत्तर

15

समस्या यह है कि आपके Wrapper वस्तु एक अस्थायी रूप में निर्माण किया जा रहा है और उसे तुरंत नष्ट है। operator char* के माध्यम से आप स्मृति में एक पॉइंटर लौट रहे हैं जिसे Wrapper ऑब्जेक्ट द्वारा नष्ट कर दिया गया था जब इसे हटा दिया गया था।

यह काम करने के लिए:

Wrapper wrapper("Kevin"); 
char* username = wrapper; 
+1

धन्यवाद। यह आश्चर्यजनक रूप से तेज़ है। –

+2

@ sankaran1984 उसे एक पक्ष करो और जवाब स्वीकार करें, यह बाईं ओर बड़ा चेकमार्क है। = पी – James

+1

उत्तरदाताओं के लिए एक एसओ नौसिखिया से भी एक अच्छी तरह से व्यक्त प्रश्न को ऊपर उठाने के लिए अच्छा हो सकता है। –

4

यह पंक्ति:

char* username = Wrapper("kevin"); 

एक अनाम आवरण वस्तु जो तुरंत नष्ट हो जाता है, कुछ भी नहीं पर अपने सूचक की ओर इशारा करते छोड़ने पैदा करता है। आपको या तो रैपर ऑब्जेक्ट को एक नाम देना होगा, या उस तरह कोड नहीं लिखना होगा। यह काम करेगा:

Wrapper w("kevin"); 
char* username = w; 
printf("%s", username); 
4

सूचक आप लौट रहे हैं जैसे ही यह पहले बयान के अंत में क्षेत्र से बाहर चला जाता है आवरण नाशक से हटाया जा रहा है - printf से पहले।
कुछ मामलों में, इस बग को कवर किया जा सकता है क्योंकि स्मृति को तुरंत पुनः प्राप्त नहीं किया जा सकता है और मान "ठीक" दिखता है भले ही यह अब मान्य नहीं है। कुछ उपकरण इसका पता लगाने में मदद कर सकते हैं।

char* username = Wrapper("kevin"); 

बयान के अंत में, ("पूर्ण अभिव्यक्ति") Wrapper वस्तु को नष्ट कर दिया जाता है:

1

यह बयान एक अस्थायी Wrapper वस्तु बनाता है। आपको एक लटकते सूचक के साथ छोड़ दिया गया है (यानी, जो इसे इंगित करता है उसे हटा दिया गया है)।

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