2011-01-01 11 views
5

से मुक्त किया जा सकता है, मैंने इसका उत्तर देने के लिए पूरी तरह से देखा है लेकिन एक ऐसा प्रतीत नहीं होता है। (मेरे पास सी ++ के साथ काफी सीमित अनुभव है)यह देखने के लिए जांच कर रहा है कि क्या पॉइंटर को

मेरी लाइब्रेरी में, मैं एक स्ट्रिंग मुक्त करता हूं। (कमाल, हुह?)

यह वह समस्या है जहां समस्या उत्पन्न होती है। मेरे पास एक संरचना है जिसमें एक char * है जिसे ढेर पर आवंटित किया जा सकता है या नहीं हो सकता है। हालांकि यह एक वैध सूचक है, इसे मुक्त नहीं किया जा सकता है।

आईई

char* s1 = "A String"; 
char* s2 = (char*)memcpy(malloc(9), s1, 9); 

free(s2); 
free(s1); 

पर एक त्रुटि का कारण होगा "मुक्त (S1);" (जैसा कि यह होना चाहिए) क्योंकि एस 1 वास्तव में को मुक्त करने के लिए की आवश्यकता नहीं है, (यह ढेर पर नहीं है) मैं इसे "स्वीकार्य" तरीके से कैसे संभाल सकता हूं? (इसी तरह के विषयों पर "इसे क्रैश करने दें" का जवाब उचित आईएमओ नहीं लग रहा था)

क्योंकि संरचना पूरी तरह से लाइब्रेरी द्वारा बनाई गई नहीं है, इसलिए यह गारंटी देना संभव नहीं है कि किसी स्ट्रिंग को कुछ उपयोग करने पर ठीक से कॉपी किया जाएगा memcpy की तरह।

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

+0

सर्वश्रेष्ठ उत्तर (IMHO): गारंटी नहीं है कि 'struct' केवल लाइब्रेरी में बनाए _is_ एक अपारदर्शी सूचक का प्रयोग करें। (अगर मैं विंडोज का उपयोग करता हूं तो मैं और मदद की पेशकश करूंगा। क्षमा करें। +1 हालांकि।) –

+0

धन्यवाद, अगर सबसे खराब सबसे खराब आता है तो मैं या तो ऐसा कर सकता हूं या एसईएच का उपयोग कर सकता हूं (हालांकि बाद वाला मुझे ऐसा महसूस कर देगा कि मैं कुछ गलत कर रहा था) – James

+0

यह एक विंडोज लाइब्रेरी है, यह तर्क एक BSTR तर्क बनाते हैं। फिर आपको उपयोगकर्ता को इसे ठीक से आवंटित करने की आवश्यकता होती है ('SysAllocString' के साथ) और आपको मिलान करने वाले डेलोकेटर का उपयोग करने की गारंटी है। अन्य विधियां सिर्फ ... खराब हैं। यदि आपके उपयोगकर्ता के पास एक अलग कंपाइलर है, तो आप 'malloc' –

उत्तर

2

यह एक विंडोज लाइब्रेरी के रूप में देखकर, BSTR तर्क दें। फिर आपको उपयोगकर्ता को इसे ठीक से आवंटित करने की आवश्यकता होती है (SysAllocString के साथ) और आपको a matching deallocator का उपयोग करने की गारंटी है।

अन्य विधियां सिर्फ ... खराब हैं। यदि आपके उपयोगकर्ता के पास एक अलग कंपाइलर है, तो आप स्ट्रिंग free() स्ट्रिंग नहीं कर सकते हैं भले ही उन्होंने malloc का उपयोग किया हो।

:

इसके अलावा नोट [नोट जेम्स के अनुरोध पर एक टिप्पणी से परिवर्तित, यह वास्तव में his suggestions के अंतिम में से केवल एक Windows विशेष मामला है]: BSTR यूनिकोड है। मैं थोड़े तरह से एएनएसआई तारों को स्टोर करने के लिए BSTR आवंटक का उपयोग करने का तरीका देख रहा हूं, ऐसा लगता है कि SysAllocStringByteLen ऐसा करता है, लेकिन चेतावनी दी जाती है कि बीएसटी में एएनएसआई डेटा डालने से बीस्ट्रेट से परिचित किसी के लिए अत्यधिक प्रतिकूल होगा।

+0

ठीक है, लेकिन मुझे लगता है कि मूल सी ++ से .NET कोड से निपटने के दौरान मुझे इसका उपयोग करने की आवश्यकता थी (और SAFEARRAY) जब मुझे बीएसटी के साथ कुछ बुरे अनुभव होते हैं। हालांकि यह ऑफ-विषय है, लेकिन मैं इसे आज़मा दूंगा। – James

+0

@ जेम्स: मुझे संदेह है कि यह COM कोड था जिसने कठिनाई का कारण बना दिया और बीएसटी नहीं। बीएसटी फ़ंक्शंस वास्तव में वास्तव में सरल और सी या सी ++ से उपयोग करने में आसान हैं। मुझे लगता है कि वीसी ++ भी बीएसटी को स्वचालित रूप से मुक्त करने के लिए एक रैपर वर्ग प्रदान करता है क्योंकि यह गुंजाइश से बाहर हो जाता है, लेकिन इसमें अधिक कार्यक्षमता नहीं होती है और यह नहीं जानती कि यह मुझे कैसे परेशान करता है, इसलिए मुझे हमेशा 'SysAllocString' और' SysFreeString 'कहा जाता है सीधे –

6

सी ++ में, आपको इसके बारे में चिंता नहीं करनी चाहिए। std::string का उपयोग करें और इसे स्वचालित रूप से आपके लिए स्मृति प्रबंधित करें। Don't manage memory manually.

आप इस मैन्युअल रूप से करने के लिए थे, तो आप पुस्तकालय के उपयोगकर्ता स्मृति खुद का प्रबंधन कर रही संसाधन खुद के प्रबंधन करने के लिए, द्वारा

  • की आवश्यकता होगी, या
  • उपयोगकर्ता की आवश्यकता होती है आपको बताने के लिए मेमोरी का प्रबंधन कैसे करें, या
  • उपयोगकर्ता को बता रहा है कि आप स्मृति को प्रबंधित करने के लिए कैसे जा रहे हैं और फिर उपयोगकर्ता को अनुपालन करने की उम्मीद है।
+1

टिप्पणियों के मुताबिक, यह विंडोज़ पर लाइब्रेरी (2) और (3) स्पष्ट रूप से पहले से संकलित है, इस तथ्य को छोड़कर यह बहुत अच्छी सलाह है। और 'std :: string' को Windows पर मॉड्यूल सीमाओं को पार करने के लिए असुरक्षित निर्णय लिया गया है। Win32 एपीआई के पैटर्न के बाद, आपके द्वारा दी जाने वाली पहली बुलेट विंडोज लाइब्रेरीज़ को मेमोरी को संभालने के लिए पसंदीदा तरीका है। –

+0

@ बेन: विंडोज प्रोग्रामिंग: मेरा फोर्टे नहीं (मजाकिया, मुझे लगता है)। आप सही हैं, ज़ाहिर है: यदि आप पुस्तकालय और इसके खिलाफ जो भी लिंक दोनों के लिए निर्माण प्रक्रिया को नियंत्रित नहीं कर सकते हैं, तो यह काफी समस्याग्रस्त होगा। यदि आपने इसे उत्तर के रूप में पोस्ट किया है तो मैं आपके BSTR समाधान को ऊपर उठाऊंगा। यह सबसे उचित समाधान है, आईएमओ। –

0

आप char *s1 malloc कर सकते हैं और "A String" मूल्य के रूप में रख सकते हैं। उसके बाद, आप s1 मुक्त कर सकते हैं।

+0

मुझे पता है, लेकिन अगर कोई संरचना-> वैल = "यादृच्छिक" चला जाता है; तो मुझे फिर से समस्याएं मिलती हैं – James

0

यह ऐसी चीज है जो संकलन समय पर ज्ञात है। आप कोड को देखते हैं और जानते हैं कि क्या मुक्त करना है और क्या नहीं। तो रनटाइम पर इसे स्थगित करने के तरीके के बारे में मत सोचें, क्योंकि इस तथ्य के अलावा आपको इस मामले में कोई रास्ता नहीं मिलेगा, यह सी ++ में चीजों को करने का गलत तरीका है। जब आप इसे स्थिर रूप से कर सकते हैं, तो इसे स्थिर रूप से करें।

टाइप सिस्टम का उपयोग करें। आरएआईआई का प्रयोग करें।

+0

समस्या यह है कि यह __my__ संकलन समय पर नहीं जानता है, केवल उन लोगों के लिए जो वास्तव में मेरी लाइब्रेरी को बुला रहे हैं। एक सूचक सिर्फ एक संख्या है। – James

+1

@ जेम्स यह ** स्वामित्व ** है। पूछने का सवाल यह है कि सूचक का मालिक कौन है। यह कुछ है जो आप फ़ंक्शन के दस्तावेज़ में कहते हैं। किसी भी तरह से, कॉलर को यह जांचना नहीं चाहिए कि उसे सूचक को मुक्त करना चाहिए या नहीं। फिर, यह स्थिर जानकारी है जिसके बारे में आपको स्पष्ट होना चाहिए। – wilhelmtell

0

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

+0

किस ढेर? विंडोज़ पर, प्रत्येक लाइब्रेरी को अपना असंगत मैलोक/फ्री ढेर मिल जाता है। विन 32 एपीआई 'हेपअलोक' और 'हेपफ्री' मॉड्यूल सीमाओं में काम करता है, लेकिन वे सीआरटी-प्रदत्त मॉलोक के साथ संगत नहीं हैं और किसी भी मॉड्यूल में निःशुल्क हैं। –

+0

मैलोक() द्वारा उपयोग की जाने वाली ढेर, ओपी ने ढेर पर संग्रहीत स्ट्रिंग को आवंटित करने के तरीके के अनुसार। –

0

मैंने अतीत में कुछ ऐसा किया है, जहां मैं कुछ मामलों में एक स्टैक-आवंटित स्ट्रिंग का उपयोग करता हूं, और दूसरों में एक ढेर-आवंटित स्ट्रिंग का उपयोग करता हूं, लेकिन अंततः वे किसी अन्य सामान्य कोड को पारित कर देते हैं।

मैंने जो मामले में किया है, वह दो पॉइंटर्स है। एक या तो नल, या एक ढेर आवंटित स्ट्रिंग है। दूसरा पॉइंटर या तो स्टैक-आवंटित या एक ही ढेर-आवंटित स्मृति को पूर्व के रूप में इंगित करता है। जब आप अपना मुफ्त() करने के लिए जाते हैं, तो आप केवल पूर्व सूचक की जांच करते हैं।

बेशक, यह एक उजागर एपीआई में बुरा दिखने वाला है। मेरे मामले में यह केवल आंतरिक कोड था।

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