2012-07-16 19 views
5

पर सरोगेट जोड़ी (बीएमपी से यूनिकोड चरित्र) के लिए wchar_t * का आकार मुझे विंडोज 8 पर एक दिलचस्प समस्या आई है। मैंने परीक्षण किया है कि मैं यूनिकोड वर्णों का प्रतिनिधित्व कर सकता हूं जो wchar_t * तारों के साथ बीएमपी से बाहर हैं। निम्न परीक्षण कोड मेरे लिए अप्रत्याशित परिणाम का उत्पादन:विंडोज

const wchar_t* s1 = L"a"; 
const wchar_t* s2 = L"\U0002008A"; // The "Han" character 

int i1 = sizeof(wchar_t); // i1 == 2, the size of wchar_t on Windows. 

int i2 = sizeof(s1); // i2 == 4, because of the terminating '\0' (I guess). 
int i3 = sizeof(s2); // i3 == 4, why? 

U + 2008A Han character, जो बाइनरी बहुभाषी फलक से बाहर है, तो यह UTF-16 में एक सरोगेट जोड़ी द्वारा प्रतिनिधित्व किया जाना चाहिए। जिसका अर्थ है - अगर मैं इसे सही ढंग से समझता हूं - कि इसे दो wchar_t वर्णों द्वारा दर्शाया जाना चाहिए। तो मुझे लगता है कि आकार (एस 2) 6 होना चाहिए (सरोगेट जोड़ी के दो wchar_t-s के लिए 4 और समाप्ति के लिए 2)।

तो आकार (एस 2) == 4 क्यों है? मैंने परीक्षण किया कि एस 2 स्ट्रिंग का सही ढंग से निर्माण किया गया है, क्योंकि मैंने इसे DirectWrite के साथ प्रस्तुत किया है, और हान चरित्र सही ढंग से प्रदर्शित किया गया था।

अद्यतन: जैसा कि नवीन ने बताया, मैंने गलत तरीके से सरणी के आकार को निर्धारित करने की कोशिश की। निम्नलिखित कोड सही परिणाम पैदा करता है:

const wchar_t* s1 = L"a"; 
const wchar_t* s2 = L"\U0002008A"; // The "Han" character 

int i1 = sizeof(wchar_t); // i1 == 2, the size of wchar_t on Windows. 

std::wstring str1 (s1); 
std::wstring str2 (s2); 

int i2 = str1.size(); // i2 == 1. 
int i3 = str2.size(); // i3 == 2, because two wchar_t characters needed for the surrogate pair. 

उत्तर

8

sizeof(s2) सूचक s2 या किसी अन्य सूचक है, जो आपके सिस्टम पर 4 बाइट्स स्टोर करने के लिए आवश्यक बाइट की संख्या देता है। में s2 द्वारा संग्रहीत चरित्र (ओं) के साथ इसका कोई लेना-देना नहीं है।

+0

निश्चित रूप से सही है, धन्यवाद है। बेवकूफ सवाल के लिए सूखी ... –

+0

"एस 2 में संग्रहीत चरित्र के साथ इसका कोई लेना-देना नहीं है" - चूंकि प्रश्न पॉइंटर्स और चीजों के बीच गलतफहमी के कारण हुआ था, इसलिए आपको इस तरह की एक और गलतफहमी पैदा करने से बचना चाहिए। एस 2 में कोई चरित्र संग्रहित नहीं है। इस मामले में एस 2 [0] और एस 2 [1] में संग्रहित एक चरित्र है। अगर यह एक सरोगेट जोड़ी नहीं थी तो अकेले एस 2 [0] में संग्रहित एक चरित्र होगा, यानी * एस 2 में। –

+0

@ विन्डोजप्रोग्रामर: फिक्स्ड। –

4

sizeof(wchar_t*)sizeof(void*) जैसा ही है, दूसरे शब्दों में एक पॉइंटर का आकार ही है। यह 32-बिट सिस्टम पर हमेशा 4 होगा, और 64-बिट सिस्टम पर 8 होगा। आप sizeof() के बजाय wcslen() या lstrlenW() उपयोग करने की आवश्यकता: उत्तर देने के लिए

const wchar_t* s1 = L"a"; 
const wchar_t* s2 = L"\U0002008A"; // The "Han" character 

int i1 = sizeof(wchar_t); // i1 == 2 
int i2 = wcslen(s1); // i2 == 1 
int i3 = wcslen(s2); // i3 == 2 
+0

"sizeof (wchar_t *) आकार के समान है (शून्य *)" - यह मेरी समझ नहीं है। sizeof (char *), sizeof (हस्ताक्षरित char *), और sizeof (unsigned char *) आकार के समान आकार (शून्य *) हैं। आकार (wchar_t *) और sizeof (अन्य यादृच्छिक सामान) कार्यान्वयन के आधार पर आकार (शून्य *) से छोटा हो सकता है। –

+0

@ विन्डोजप्रोग्रामर: सही - हालांकि आधुनिक कंप्यूटर्स के विशाल बहुमत सभी सूचक प्रकारों को एक ही आकार में बनाते हैं। –

+0

कोई संकलक क्यों होगा, सी/सी ++ स्टैंडेंड को अकेले छोड़ दें, किसी भी आकार का आकार (कोई सूचक प्रकार) 'आकार (शून्य *)' से छोटा हो सकता है? आकार() के परिप्रेक्ष्य से, एक सूचक एक सूचक है एक सूचक है, इससे कोई फर्क नहीं पड़ता है। –

0

परिशिष्ट।
आरई: i1 और i2, i3 द्वारा प्रश्न के अद्यतन में उपयोग की जाने वाली विभिन्न इकाइयों को जानने के लिए।

2 की

i1 मूल्य बाइट में आकार है 1 की
i2 मूल्य आकार wchar_t में, IOW 4 बाइट्स (sizeof(wchar_t) संभालने 4 है)।
i3 2 का मूल्य wchar_t में आकार, IOW 8 बाइट्स