2010-06-24 12 views
8

इसमें क्या गलत है:wchar_t सूचक

wchar_t * t = new wchar_t; 

t = "Tony"; 

मैंने सोचा कि मैं एक स्ट्रिंग के रूप में एक wchar_t सूचक इस्तेमाल कर सकते हैं ...

+0

की [संभव डुप्लिकेट बात करने के लिए सूचक क्या इस कोड के साथ गलत है प्रदान करती है ?] (http://stackoverflow.com/questions/3080137/what-is-wrong-with-this-code) या http://stackoverflow.com/questions/1577765/why-must-a-pointer-to- ए-char-array-need-strcpy-to-assign-characters-to-its-array – bk1e

उत्तर

25

आपका कोड दो मुद्दे हैं।

पहला, "Tony"char की स्ट्रिंग के लिए एक सूचक है। L"Tony" उचित चौड़ा स्ट्रिंग है।

दूसरा, आप नए के माध्यम से एक एकल wchar_t आवंटित करते हैं, फिर तुरंत टोनी को पॉइंटर को पुन: असाइन करके इसका ट्रैक खो देते हैं। इसका परिणाम स्मृति रिसाव में होता है।

+4

माइकल के स्पष्टीकरण पर विस्तार करने के लिए, सही वाक्यविन्यास 'wchar_t * t = L "टोनी" होगा; '। यह एक सूचक घोषित करेगा और स्थिर (चौड़ी) स्ट्रिंग "टोनी" को इंगित करने के लिए इसे प्रारंभ करेगा। – bta

+3

वाक्यविन्यास वास्तव में 'wchar_t const * t = l "टोनी" होना चाहिए; '। यह देखने के लिए, कथन पर विचार करें * * (टी + 1) = एल 'i'; ' – MSalters

-1

यह पूरी तरह से गलत है। दो बाइट आवंटित करने की कोई आवश्यकता नहीं है, उन्हें इंगित करने के लिए टी बनाएं, और उसके बाद खोए हुए स्मृति को हमेशा के लिए लीक करने वाले पॉइंटर टी को ओवरराइट करें।

इसके अलावा, "टोनी" का एक अलग प्रकार है। उपयोग:

wchar_t *t = L"Tony";

IMHO बेहतर बिल्कुल wchars उपयोग न करें - देखें https://stackoverflow.com/questions/1049947/should-utf-16-be-considered-harmful

+0

शायद एक टाइपो लेकिन wchar_t t = ... wchar_t * t = ... –

+0

निश्चित, thx होना चाहिए। एक tpyo .. –

+4

इसके अलावा एक wchar_t आवश्यक दो बाइट्स नहीं है। जीसीसी के संस्करण में मैं wchar_t का उपयोग कर रहा हूं 4 बाइट्स, और मानक कहता है कि यह संकलक विशिष्ट है। यह एक बाइट भी हो सकता है। –

5

यह क्या करता है पहले t में करने के लिए एक नव wchar_t आवंटित एक सूचक आवंटित है, और फिर t में एक गैर विस्तृत स्ट्रिंग आवंटित करने के लिए प्रयास करें।

क्या आप इसके बजाय std::wstring का उपयोग कर सकते हैं? यह आपके लिए आपकी सभी मेमोरी प्रबंधन आवश्यकताओं को संभालेगा।

+0

wstring केवल एमएसवीसी में मौजूद है। यह मानक नहीं है। –

+6

@ पावेल: यह बहुत गलत है। wstring 'typedef''ed 'basic_string ' के रूप में है और * हर * अनुपालन सी ++ सिस्टम/टूलचेन पर मौजूद है। – rubenvb

+6

@ पावेल: §21.2/2: "हेडर' 'दो विशिष्ट टेम्पलेट वर्ग' स्ट्रिंग' और 'wstring' और उनके विशेष लक्षण भी परिभाषित करता है। " – GManNickG

0

आप यह कर सकते हैं कि "टोनी" एक हार्डकोडेड स्ट्रिंग है, और वे ज्यादातर संपादकों/कंपाइलरों में डिफ़ॉल्ट रूप से एएनएसआई हैं। यदि आप संपादक को बताना चाहते हैं तो आप यूनिकोड स्ट्रिंग में टाइप कर रहे हैं, फिर इसे एल के साथ उपसर्ग करें, उदा। t = L"Tony"

आपको अपने कोड के साथ अन्य समस्याएं हैं, आपका आवंटन एक यूनिकोड चरित्र (2 बाइट्स) आवंटित कर रहा है, तो आप मूल चर को स्थिर स्ट्रिंग पर इंगित करने की कोशिश कर रहे हैं, इस प्रकार उन 2 बाइट्स को लीक कर रहे हैं।

आप इसे में यूनिकोड डेटा और जगह डेटा की एक बफर बनाने के लिए चाहते हैं, आप क्या करना चाहते:

wchar_t* t = new wchar_t[500]; 
wcscpy(t, "Tony"); 
+0

wchar_t का आकार कंपाइलर विशिष्ट है और 1 बाइट जितना छोटा हो सकता है और 4 के रूप में बड़ा हो सकता है। –

11

एक संकेतक बस एक ही मूल्य के लिए कहते हैं। यह महत्वपूर्ण है।

आपके द्वारा किए गए सभी को एक ही wchar_t के लिए आवंटित किया गया कमरा है, और उस पर इंगित करें। फिर आप पॉइंटर को स्ट्रिंग पर इंगित करने का प्रयास करते हैं (याद रखें, केवल पहले अक्षर पर), लेकिन स्ट्रिंग प्रकार गलत है।

आपके पास char की एक स्ट्रिंग है, यह "L"Tony" होनी चाहिए"। लेकिन आप यहां जो कुछ कर रहे हैं वह आपकी पिछली मेमोरी आवंटन को लीक कर रहा है क्योंकि सूचक के पास एक नया मूल्य है।

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

बस std::wstring का उपयोग करें और आगे बढ़ें। std::wstring t = L"Tony";।यह सभी विवरणों को संभालता है, और आपको कुछ भी साफ करने की चिंता करने की आवश्यकता नहीं है।

+2

आईएमओ सबसे सही उत्तर और 'std का उपयोग करने के साथ :: wstring', सबसे अच्छी सलाह। – sbi

+0

@ एसबीआई: धन्यवाद क्यों। :) – GManNickG

+1

उत्कृष्ट जवाब। –

5

चूंकि आप एक सी # डेवलपर हैं, इसलिए मैं कुछ चीजों को इंगित करूंगा सी ++ अलग-अलग है।

यह एक नया wchar_t आवंटित करता है और यह प्रदान करती है

wchar_t* t = new wchar_t 

टी के लिए यह लगातार चार की एक सरणी है

"Tony" 

एक निरंतर wchar_t सरणी उपसर्ग यह एल के साथ प्राप्त करने के लिए

L"Tony" 

यह आपके पुराने wchar_t के बजाय निरंतर एल "टोनी" को इंगित करने के लिए टी को पुन: असाइन करता है और स्मृति रिसाव का कारण बनता है चूंकि आपका wchar_t कभी जारी नहीं किया जाएगा।

t = L"Tony" 

यह एल की एक प्रतिलिपि "टोनी"

std::wstring t = L"Tony" 

मुझे लगता है कि अंतिम पंक्ति तुम क्या चाहते है धारण करने के लिए विस्तृत वर्ण के एक स्ट्रिंग (wchar_t) पैदा करता है। यदि आपको wchar_t पॉइंटर का उपयोग t.c_str() तक पहुंच की आवश्यकता है। ध्यान दें कि सी ++ स्ट्रिंग्स म्यूटेबल हैं और प्रत्येक असाइनमेंट पर कॉपी की गई हैं।

करने के लिए ग तरीका यह

const wchar_t* t = L"Tony" 

यह एक प्रति का निर्माण नहीं करता होगा और केवल स्थिरांक wchar सरणी

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