क्या एक शून्य पॉइंटर को हटाना सुरक्षित है?


96

मान लीजिए कि मेरे पास निम्नलिखित कोड हैं:

void* my_alloc (size_t size)
{
   return new char [size];
}

void my_free (void* ptr)
{
   delete [] ptr;
}

क्या यह सुरक्षित है? या विलोपन ptrसे char*पहले डाला जाना चाहिए ?


आप स्मृति प्रबंधन स्वयं क्यों कर रहे हैं? आप किस डेटा संरचना का निर्माण कर रहे हैं? स्पष्ट स्मृति प्रबंधन करने की आवश्यकता C ++ में बहुत दुर्लभ है; आपको आमतौर पर एसटीएल (या एक चुटकी में बूस्ट) से आपके लिए इसे संभालने वाली कक्षाओं का उपयोग करना चाहिए।
ब्रायन

6
सिर्फ पढ़ने वाले लोगों के लिए, मैं जीत c ++ में अपने थ्रेड्स के पैरामीटर के रूप में शून्य * चर का उपयोग करता हूं (देखें _beginthreadex)। आमतौर पर वे कक्षाओं को इंगित करते हैं।
रयानस्टैक

3
इस मामले में यह नए / हटाने के लिए एक सामान्य उद्देश्य आवरण है, जिसमें आवंटन ट्रैकिंग आँकड़े या एक अनुकूलित मेमोरी पूल हो सकता है। अन्य मामलों में, मैंने ऑब्जेक्ट पॉइंटर्स को गलत तरीके से शून्य * सदस्य चर के रूप में संग्रहीत किया है, और उचित ऑब्जेक्ट प्रकार पर वापस कास्टिंग के बिना विध्वंसक में गलत तरीके से हटा दिया गया है। इसलिए मैं सुरक्षा / नुकसान के बारे में उत्सुक था।
21

1
नए / हटाने के लिए एक सामान्य प्रयोजन के आवरण के लिए आप नए / हटाए गए ऑपरेटरों को अधिभारित कर सकते हैं। आपके द्वारा उपयोग किए जाने वाले पर्यावरण के आधार पर, आपको आवंटन को ट्रैक करने के लिए संभवतः स्मृति प्रबंधन में हुक मिलते हैं। यदि आप एक ऐसी स्थिति में समाप्त होते हैं, जहां आपको नहीं पता कि आपका क्या हट रहा है, तो इसे एक मजबूत संकेत के रूप में लें कि आपका डिज़ाइन सब-ऑप्टिमल है और रिफैक्टरिंग की आवश्यकता है।
हंस

38
मुझे लगता है कि सवाल का जवाब देने के बजाय सवाल करना बहुत ज्यादा है। (न केवल यहां, बल्कि सभी एसओ में)
पेटरुजा

जवाबों:


24

यह "सुरक्षित" पर निर्भर करता है। यह आमतौर पर काम करेगा क्योंकि आवंटन के बारे में सूचक के साथ ही जानकारी संग्रहीत होती है, इसलिए डीलक्लॉकर इसे सही जगह पर वापस कर सकता है। इस अर्थ में यह "सुरक्षित" है जब तक कि आपका आवंटनकर्ता आंतरिक सीमा टैग का उपयोग करता है। (कई)

हालांकि, जैसा कि अन्य उत्तरों में बताया गया है, एक शून्य पॉइंटर को हटाने से डिस्ट्रक्टर्स को कॉल नहीं किया जाएगा, जो एक समस्या हो सकती है। उस अर्थ में, यह "सुरक्षित" नहीं है।

आप जो कर रहे हैं, उसे करने का कोई अच्छा कारण नहीं है। यदि आप अपने स्वयं के डील-डौल कार्यों को लिखना चाहते हैं, तो आप सही प्रकार के कार्यों को उत्पन्न करने के लिए फ़ंक्शन टेम्प्लेट का उपयोग कर सकते हैं। ऐसा करने का एक अच्छा कारण यह है कि पूल आवंटनकर्ता उत्पन्न होते हैं, जो विशिष्ट प्रकारों के लिए अत्यंत कुशल हो सकते हैं।

जैसा कि अन्य उत्तरों में बताया गया है, यह C ++ में अपरिभाषित व्यवहार है। सामान्य तौर पर यह अपरिभाषित व्यवहार से बचने के लिए अच्छा है, हालांकि यह विषय स्वयं जटिल है और परस्पर विरोधी विचारों से भरा है।


9
यह एक स्वीकृत उत्तर कैसे है? यह "एक शून्य पॉइंटर को हटाने" का कोई मतलब नहीं है - सुरक्षा एक बिंदु है।
केरेक एसबी

6
"आप जो कर रहे हैं, उसे करने का कोई अच्छा कारण नहीं है।" यह आपकी राय है, तथ्य नहीं है।
3

8
@rxantos एक काउंटर उदाहरण प्रदान करते हैं जहां प्रश्न के लेखक क्या करना चाहते हैं, यह C ++ में एक अच्छा विचार है।
क्रिस्टोफर

मुझे लगता है कि यह उत्तर वास्तव में उचित है, लेकिन मुझे यह भी लगता है कि इस प्रश्न के किसी भी उत्तर को कम से कम उल्लेख करने की आवश्यकता है कि यह अपरिभाषित व्यवहार है।
काइल स्ट्रैंड

@ क्रिस्‍टोफर एक एकल कचरा संग्राहक प्रणाली लिखने का प्रयास करें, जो विशिष्ट नहीं है, लेकिन केवल काम करती है। तथ्य यह है कि sizeof(T*) == sizeof(U*)सभी के लिए T,Uसुझाव है कि यह संभव होना चाहिए 1 गैर अस्थायी, void *आधारित कचरा कलेक्टर कार्यान्वयन। लेकिन तब, जब gc को वास्तव में एक पॉइंटर को डिलीट / फ्री करना होता है, तो यह सवाल उठता है। इसे काम करने के लिए, आपको या तो लैम्ब्डा फंक्शन डिस्ट्रक्टर रैपर (उरग) की आवश्यकता होती है या आपको किसी प्रकार के गतिशील "टाइप द डेटा" प्रकार की आवश्यकता होती है, जो एक प्रकार और कुछ स्टैग के बीच आगे और पीछे की अनुमति देता है।
BitTickler

147

शून्य सूचक द्वारा हटाना C ++ मानक द्वारा अपरिभाषित है - खंड 5.3.5 / 3 देखें:

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

और इसके फुटनोट:

इसका तात्पर्य यह है कि किसी वस्तु को प्रकार void * के सूचक का उपयोग करके हटाया नहीं जा सकता है क्योंकि वहाँ प्रकार की कोई वस्तु शून्य नहीं है


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

2
आप सही हैं - मैंने जवाब अपडेट कर दिया है। मुझे नहीं लगता कि यह मूल बिंदु की उपेक्षा करता है?

नहीं बिलकुल नहीं। यह अभी भी कहता है कि यह यूबी है। इससे भी अधिक तो, अब यह यह कहा गया normatively कि शून्य * को हटाने यूबी है :)
Johannes Schaub - litb

NULLएप्लिकेशन मेमोरी प्रबंधन के लिए कोई अंतर बनाने के साथ एक शून्य पॉइंटर की इंगित पता मेमोरी भरें ?
आर्टू-ह्नर्क

25

यह एक अच्छा विचार नहीं है और ऐसा कुछ नहीं है जो आप C ++ में करेंगे। आप बिना किसी कारण के अपने प्रकार की जानकारी खो रहे हैं।

आपके विनाशकर्ता को आपके सरणी में उन वस्तुओं पर नहीं बुलाया जाएगा जिन्हें आप गैर-आदिम प्रकारों के लिए कॉल करते समय हटा रहे हैं।

आपको इसके बजाय नया / हटाना ओवरराइड करना चाहिए।

शून्य को हटाना * संभवतः आपकी स्मृति को सही ढंग से संयोग से मुक्त कर देगा, लेकिन यह गलत है क्योंकि परिणाम अपरिभाषित हैं।

अगर किसी कारण से मेरे लिए अज्ञात है तो आपको अपने पॉइंटर को एक शून्य में संग्रहीत करने की आवश्यकता है * फिर इसे मुक्त करें, आपको मॉलोक और मुफ्त का उपयोग करना चाहिए।


5
आप विध्वंसक नहीं कहे जाने के बारे में सही हैं, लेकिन आकार अज्ञात होने के बारे में गलत है। आप एक सूचक है कि आप नए से मिला हटाना देते हैं, यह है वास्तव में पता बात के आकार को नष्ट कर दिया जा रहा है, पूरी तरह से अलग प्रकार। यह कैसे करता है यह सी ++ मानक द्वारा निर्दिष्ट नहीं है, लेकिन मैंने उन कार्यान्वयनों को देखा है जहां डेटा उस डेटा से पहले संग्रहीत किया जाता है जिसे सूचक 'नए' बिंदुओं से लौटाता है।
KeyserSoze

आकार के बारे में भाग को हटा दिया, हालांकि सी ++ मानक का कहना है कि यह अपरिभाषित है। मुझे पता है कि मॉलॉक / मुक्त काम करेगा हालांकि शून्य * पॉइंटर्स के लिए।
ब्रायन आर बॉडी

मान लीजिए कि आपके पास मानक के संबंधित अनुभाग में एक वेबलिंक नहीं है? मुझे पता है कि नए / हटाए जाने के कुछ कार्यान्वयन मैंने निश्चित रूप से टाइप ज्ञान के बिना सही ढंग से काम करने के लिए देखा है, लेकिन मैं मानता हूं कि मैंने यह नहीं देखा है कि मानक क्या निर्दिष्ट करता है। IIRC C ++ मूल रूप से सरणियों को हटाते समय एक सरणी तत्व गणना की आवश्यकता होती है, लेकिन अब नवीनतम संस्करणों के साथ नहीं करता है।
KeyserSoze

कृपया @Neil Butterworth उत्तर देखें। उनका जवाब मेरी राय में स्वीकार किया जाना चाहिए।
ब्रायन आर बॉडी

2
@keyseroze: आमतौर पर मैं आपके कथन से सहमत नहीं हूं। सिर्फ इसलिए कि कुछ क्रियान्वयन ने मेमोरी को स्टोर करने से पहले आकार को स्टोर किया था, इसका मतलब यह नहीं है कि यह एक नियम है।

13

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


1
char में कंस्ट्रक्टर / डिस्ट्रक्टर नहीं है।
rxantos 3

9

सवाल कोई मतलब नहीं है। आपके भ्रम का कारण आंशिक रूप से उस फूहड़ भाषा के कारण हो सकता है जिसका लोग अक्सर उपयोग करते हैं delete:

आप deleteएक ऐसी वस्तु को नष्ट करने के लिए उपयोग करते हैं जिसे गतिशील रूप से आवंटित किया गया था। ऐसा करने पर, आप उस ऑब्जेक्ट के लिए एक पॉइंटर के साथ एक डिलीट एक्सप्रेशन बनाते हैं । आप कभी भी "एक पॉइंटर हटाएं" नहीं। आप वास्तव में क्या करते हैं "एक वस्तु को हटा दें जो उसके पते से पहचानी जाती है"।

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


बेशक, सवाल किसी भी आसपास के संदर्भ के बिना बहुत मायने नहीं रखता है। कुछ C ++ कंपाइलर अभी भी इस तरह के निरर्थक कोड को खुशी से संकलित करेंगे (यदि वे मददगार महसूस कर रहे हैं, तो इसके बारे में चेतावनी दे सकते हैं)। तो, यह प्रश्न पूछा गया था कि विरासत में चल रहे कोड के ज्ञात जोखिमों का आकलन करने के लिए जिसमें यह अशुभ सलाह है: क्या यह दुर्घटनाग्रस्त होगा? कुछ या सभी चरित्र सरणी स्मृति लीक? प्लेटफ़ॉर्म-विशिष्ट कुछ और है?
अन्ड्रू

विचारशील प्रतिक्रिया के लिए धन्यवाद। Upvoting!
अन्डू

1
@ और: मुझे डर है कि मानक इस पर बहुत स्पष्ट है: "ऑपरेंड का deleteमान एक शून्य सूचक मान हो सकता है, एक पिछले नए-अभिव्यक्ति द्वारा बनाई गई गैर-सरणी ऑब्जेक्ट के लिए एक पॉइंटर, या एक पॉइंटर को एक पॉइंटर इस तरह की वस्तु के आधार वर्ग का प्रतिनिधित्व करने वाला उप-विषय। यदि नहीं, तो व्यवहार अपरिभाषित है। " इसलिए यदि एक संकलक आपके कोड को नैदानिक ​​के बिना स्वीकार करता है, तो यह संकलक में बग के अलावा कुछ भी नहीं है ...
केरेक एसबी

1
@KerrekSB - यह संकलक में एक बग के अलावा कुछ भी नहीं है - मैं असहमत हूं। मानक का कहना है कि व्यवहार अपरिभाषित है। इसका मतलब है कि कंपाइलर / कार्यान्वयन कुछ भी कर सकता है और अभी भी मानक के अनुरूप हो सकता है। यदि संकलक की प्रतिक्रिया यह कहना है कि आप एक शून्य * पॉइंटर को नहीं हटा सकते, तो यह ठीक है। यदि कंपाइलर की प्रतिक्रिया हार्ड ड्राइव को मिटाना है, तो भी ठीक है। OTOH, यदि कंपाइलर की प्रतिक्रिया किसी डायग्नोस्टिक को उत्पन्न करने के लिए नहीं है, बल्कि उस कोड को उत्पन्न करती है जो उस पॉइंटर से जुड़ी मेमोरी को मुक्त करता है, वह भी ठीक है। यह यूबी के इस रूप से निपटने का एक सरल तरीका है।
डेविड हैमेन

बस जोड़ने के लिए: मैं का उपयोग नहीं कर रहा हूँ delete void_pointer। यह अपरिभाषित व्यवहार है। प्रोग्रामर को कभी भी अपरिभाषित व्यवहार नहीं करना चाहिए, भले ही प्रतिक्रिया वही करे जो प्रोग्रामर चाहता था।
डेविड हैमेन

6

यदि आप वास्तव में ऐसा करते हैं, तो मध्यम व्यक्ति ( newऔर deleteऑपरेटरों) को काटकर वैश्विक operator newऔर operator deleteसीधे क्यों नहीं बुलाया जाना चाहिए ? (बेशक, अगर आप newऔर deleteऑपरेटरों को साधने की कोशिश कर रहे हैं, तो आपको वास्तव में इसे लागू करना चाहिए operator newऔर operator delete)।

void* my_alloc (size_t size)
{
   return ::operator new(size);
}

void my_free (void* ptr)
{
   ::operator delete(ptr);
}

ध्यान दें कि इसके विपरीत malloc(), विफलता पर operator newफेंकता std::bad_allocहै (या new_handlerयदि पंजीकृत है तो कॉल करता है)।


यह सही है, क्योंकि चार में कंस्ट्रक्टर / डिस्ट्रक्टर नहीं है।
rxantos 3

5

क्योंकि चार का कोई विशेष विध्वंसक तर्क नहीं है। यह काम नहीं करेगा।

class foo
{
   ~foo() { printf("huzza"); }
}

main()
{
   foo * myFoo = new foo();
   delete ((void*)foo);
}

D'ctor बुलाया नहीं जाएगा।


5

यदि आप शून्य * का उपयोग करना चाहते हैं, तो आप सिर्फ मॉलोक / फ्री का उपयोग क्यों नहीं करते हैं? नया / हटाना केवल मेमोरी प्रबंधन से अधिक है। मूल रूप से, नए / हटाएं एक निर्माता / विध्वंसक को बुलाते हैं और कुछ और चीजें चल रही हैं। यदि आप केवल बिल्ट-इन प्रकारों (जैसे चार *) का उपयोग करते हैं और उन्हें शून्य * के माध्यम से हटाते हैं, तो यह काम करेगा लेकिन फिर भी यह अनुशंसित नहीं है। यदि आप शून्य * का उपयोग करना चाहते हैं तो लब्बोलुआब यह है कि मॉलोक / फ्री का उपयोग करें। अन्यथा, आप अपनी सुविधा के लिए टेम्पलेट फ़ंक्शंस का उपयोग कर सकते हैं।

template<typename T>
T* my_alloc (size_t size)
{
   return new T [size];
}

template<typename T>
void my_free (T* ptr)
{
   delete [] ptr;
}

int main(void)
{
    char* pChar = my_alloc<char>(10);
    my_free(pChar);
}

मैंने उदाहरण में कोड नहीं लिखा है - इस पैटर्न पर एक युगल स्थानों में उपयोग किए जाने पर ठोकर खाई, उत्सुकता से C / C ++ मेमोरी प्रबंधन को मिलाया, और सोच रहा था कि विशिष्ट खतरे क्या थे।
21

C / C ++ लिखना विफलता का एक नुस्खा है। जिसने भी लिखा है उसे एक या दूसरे को लिखना चाहिए था।
डेविड थॉर्नले

2
@David वह C ++ है, C / C ++ नहीं। C में टेम्प्लेट नहीं हैं, न ही यह नए और डिलीट का उपयोग करता है
rxantos

5

बहुत सारे लोग पहले ही यह कहते हुए टिप्पणी कर चुके हैं कि नहीं, शून्य सूचक को हटाना सुरक्षित नहीं है। मैं इसके साथ सहमत हूं, लेकिन मैं यह भी जोड़ना चाहता था कि यदि आप सन्निहित सरणियों या कुछ इसी तरह का आवंटन करने के लिए शून्य बिंदुओं के साथ काम कर रहे हैं, तो आप ऐसा कर सकते हैं newताकि आप deleteसुरक्षित रूप से (साथ, अहम) का उपयोग कर सकें , थोड़ा अतिरिक्त काम)। यह एक शून्य पॉइंटर को मेमोरी क्षेत्र (जिसे 'अखाड़ा' कहा जाता है) को आवंटित करके और फिर नए को अखाड़े को पॉइंटर की आपूर्ति करके किया जाता है। इस अनुभाग को C ++ FAQ में देखें । यह C ++ में मेमोरी पूल को लागू करने के लिए एक सामान्य दृष्टिकोण है।


0

ऐसा करने का शायद ही कोई कारण हो।

सबसे पहले, आप नहीं जानते कि अगर प्रकार डेटा की, और सब आप जानते हैं कि यह है void*, तो आप वास्तव में सिर्फ एक typeless के रूप में है कि डेटा के इलाज किया जाना चाहिए ब्लॉब बाइनरी डेटा (के unsigned char*), और उपयोग malloc/ freeइससे निपटने के लिए । तरंग डेटा और जैसी चीजों के लिए कभी-कभी इसकी आवश्यकता होती है, जहां आपको void*सी एपिस को पॉइंटर्स के आसपास से गुजरने की आवश्यकता होती है । कोई बात नहीं।

यदि आप करते हैं डेटा के प्रकार (यानी यह एक ctor / dtor है) पता है, लेकिन किसी कारण से आप एक साथ समाप्त हो गया void*सूचक (जो भी कारण के लिए आप) तो क्या तुम सच में इसे वापस प्रकार के कास्ट करना चाहिए कि आप इसे जानते हैं हो , और deleteउस पर कॉल करें ।


0

मैंने अपने ढांचे में शून्य * (उर्फ अज्ञात प्रकार) का उपयोग किया है जबकि कोड प्रतिबिंब और अस्पष्टता के अन्य करतबों में, और अब तक, मुझे किसी भी संकलक से कोई परेशानी (मेमोरी लीक, एक्सेस उल्लंघन, आदि) नहीं हुई है। ऑपरेशन अमानक होने के कारण केवल चेतावनी।

यह एक अज्ञात (शून्य *) को हटाने के लिए पूरी तरह से समझ में आता है। बस सुनिश्चित करें कि सूचक इन दिशानिर्देशों का पालन करता है, या यह समझ बनाना बंद कर सकता है:

1) अज्ञात पॉइंटर को एक प्रकार से इंगित नहीं करना चाहिए जिसमें एक तुच्छ डिकंस्ट्रक्टर है, और इसलिए जब एक अज्ञात पॉइंटर के रूप में डाला जाता है तो इसे कभी भी बंद नहीं होना चाहिए। केवल अज्ञात सूचक को हटाकर इसे मूल प्रकार में वापस डाल दें।

2) क्या स्टैक बाउंड या हीप बाउंड मेमोरी में अज्ञात पॉइंटर के रूप में संदर्भित किया जा रहा है? यदि अज्ञात पॉइंटर स्टैक पर एक उदाहरण को संदर्भित करता है, तो इसे हटा दिया जाना चाहिए!

3) क्या आप 100% सकारात्मक हैं अज्ञात पॉइंटर एक वैध मेमोरी क्षेत्र है? नहीं, तो इसे हटा दिया जाना चाहिए!

सभी में, बहुत कम प्रत्यक्ष काम है जो एक अज्ञात (शून्य *) सूचक प्रकार का उपयोग करके किया जा सकता है। हालांकि, अप्रत्यक्ष रूप से, शून्य * सी ++ डेवलपर्स के लिए एक महान संपत्ति है, जब डेटा अस्पष्टता की आवश्यकता होती है, पर भरोसा करने के लिए।


0

यदि आप केवल एक बफर चाहते हैं, तो मॉलोक / मुफ्त का उपयोग करें। यदि आपको नया / हटाना आवश्यक है, तो एक तुच्छ आवरण श्रेणी पर विचार करें:

template<int size_ > struct size_buffer { 
  char data_[ size_]; 
  operator void*() { return (void*)&data_; }
};

typedef sized_buffer<100> OpaqueBuffer; // logical description of your sized buffer

OpaqueBuffer* ptr = new OpaqueBuffer();

delete ptr;

0

चार के विशेष मामले के लिए।

चार एक आंतरिक प्रकार है जिसमें एक विशेष विध्वंसक नहीं होता है। तो लीक तर्कों में एक लूट है।

sizeof (char) आमतौर पर एक है इसलिए कोई संरेखण तर्क भी नहीं है। दुर्लभ मंच के मामले में जहां आकार (चार) एक नहीं है, वे अपने चार के लिए पर्याप्त संरेखित स्मृति आवंटित करते हैं। तो संरेखण तर्क भी एक लूट है।

इस मामले में मॉलॉक / मुक्त तेजी से होगा। लेकिन आप std :: bad_alloc को जब्त करते हैं और मॉलॉक के परिणाम की जांच करनी होती है। वैश्विक नए और डिलीट ऑपरेटरों को कॉल करना बेहतर हो सकता है क्योंकि यह मध्यम व्यक्ति को बायपास करता है।


1
" sizeof (चार) आमतौर पर एक है " sizeof (चार) हमेशा एक है
जिज्ञासु

हाल तक (2019) तक लोगों को ऐसा नहीं लगता new वास्तव में फेंकने के लिए परिभाषित किया गया है। यह सच नहीं है। यह कंपाइलर और कंपाइलर स्विच डिपेंडेंट है। उदाहरण के लिए देखें MSVC2019 /GX[-] enable C++ EH (same as /EHsc)स्विच। इसके अलावा एम्बेडेड सिस्टम पर कई लोग C ++ अपवादों के लिए प्रदर्शन करों का भुगतान नहीं करने का विकल्प चुनते हैं। तो "लेकिन आप fordit std :: bad_alloc ..." से शुरू होने वाला वाक्य संदिग्ध है।
BitTickler
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.