2009-04-30 18 views

उत्तर

70

इसके विपरीत उनके उत्तर में कुछ क्या कह रहे हैं, संभव है।

char * c = new char[N](); 

शून्य सभी पात्रों को प्रारंभ करेंगे (वास्तव में, यह मूल्य प्रारंभ कहा जाता है। लेकिन मूल्य-प्रारंभ अदिश प्रकार की एक सरणी के अपने सभी सदस्यों के लिए शून्य प्रारंभ होने जा रहा है)। यदि आप यही कर रहे हैं।

वर्थ ध्यान दें कि यह भी बिना उपयोगकर्ता घोषित निर्माता उनमें से किसी भी सदस्य जो मामले में मूल्य आरंभ नहीं हो जाता (के एरे) वर्ग-प्रकार के लिए काम करता है:

struct T { int a; }; 
T *t = new T[1](); 
assert(t[0].a == 0); 
delete[] t; 

यह कुछ विस्तार या कुछ और नहीं है। यह सी ++ 98 में भी वैसे ही काम करता था और व्यवहार करता था। बस वहां इसे मूल्य प्रारंभ करने के बजाय डिफ़ॉल्ट प्रारंभिक कहा जाता था। शून्य प्रारंभिकरण, स्केलर या पीओडी प्रकारों के स्केलर या सरणी के लिए दोनों मामलों में किया जाता है।

+1

मैं आपकी पोस्ट से प्रत्येक दिन कुछ नया सीखता हूं! बीटीडब्ल्यू, क्या आप जानते हैं कि क्यों नई [एन] (42) की अनुमति नहीं है? –

+0

टी() एक विशेष रूप है: मूल्य-प्रारंभिकरण या (यह सी ++ 98 में क्या था) डिफ़ॉल्ट-प्रारंभिक टी (42), हालांकि, प्रारंभिक प्रारंभिक है, और सरणी –

+0

के लिए काम नहीं करता है यह विशिष्ट परिदृश्य है मैं देख रहा था, लेकिन इन सभी अन्य उत्तरों भी महान हैं! – nivnad

2

नहीं। यह हमेशा डिफ़ॉल्ट होगा - आवंटित आइटम (ओं) को प्रारंभ करें, जो प्राइमेटिव के मामले में कुछ भी नहीं करता है। आपको इसे std :: uninitialized_fill_n कॉल या इसी तरह के साथ पालन करना होगा।

0

नहीं। आपको मेमोरी को मैन्युअल रूप से शून्य करना होगा। याद रखें, new स्मृति को आवंटित करने के बारे में नहीं है, बल्कि रचनाकारों के माध्यम से प्रारंभ करने के बारे में भी है। यह वह जगह है जहां calloc सी में आसान है (जिसमें प्रारंभकर्ता कार्य नहीं हैं)। आप new पर एक रैपर लिखने के लिए स्वतंत्र हैं या यहां तक ​​कि calloc का उपयोग भी करते हैं, लेकिन गैर-पीओडी वस्तुओं के लिए अधिकांश समय यह अधिक समझ में नहीं आता है।

5

नहीं। इसके अलावा भी तरह कुछ करने का नहीं लगता कि:

YourClass *var = new YourClass; 
memset(var, 0, sizeof(YourClass)); 

आप अपने vtable (अपनी कक्षा एक है) trashing लग सकती है।

मैं आपकी कक्षा की आंतरिक मेमोरी (चर) को साफ़ करने के लिए रचनाकारों का उपयोग करने की अनुशंसा करता हूं।

+3

मुझे पता नहीं है (इसमें कुछ अन्य समाधान यहाँ की तरह "प्लेसमेंट नया" का उपयोग करता है); अगर वह सचमुच पैर में खुद को गोली मारना चाहता है, तो क्या उसे रोकने के लिए नैतिक है? :-) –

+0

निश्चित रूप से अपनी कक्षा के अंदर अपनी याददाश्त आवंटित करें और सेट करें। मेमसेट पर भरोसा मत करो। यह कई मामलों में काम करता है, लेकिन यह spec में "अपरिभाषित" है। –

+0

@McWafflestic: अच्छा एक! :-) –

11

नहीं, लेकिन कॉलोक की तरह कार्य करने वाला एक नया संस्करण बनाना काफी आसान है। यह उसी तरह किया जा सकता है कि नए का नो-थ्रो संस्करण लागू किया गया है।

SomeFile.h

struct zeromemory_t{}; 
extern const zeromemory_t zeromemory; 
void* __cdcel operator new(size_t cbSize, const zeromemory_t&); 

SomeFile.cpp

const zeromemory_t zeromemory; 

void* _cdecl operator new(size_t cbSize, const zeromemory_t&) 
{ 
    void *mem = ::operator new(cbSize); 
    memset(mem,0,cbSize); 
    return mem; 
} 

अब आप कर सकते हैं zero'd स्मृति नया पाने के लिए

MyType* pMyType = new (zeromemory) MyType(); 

इसके अतिरिक्त आप आवश्यकता होगी निम्नलिखित अन्य मजेदार चीजों को करने के लिए जैसे नई परिभाषित करें [] जो काफी सीधे आगे भी है।

+2

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

+2

एस/opeartor/ऑपरेटर/बनाने के लिए इस्तेमाल किया जा सकता है, ठीक एक संकलन इकाई में ';) एक चेतावनी के रूप रखना चाहता हूँ सकता है,' का दृष्टांत को स्थिरांक zeromemory_t zeromemory सुनिश्चित करें। – ephemient

+0

@ephemient, गलत वर्तनी फिक्स्ड। उत्सुक, केवल एक .cpp फ़ाइल में परिभाषित मान को एक से अधिक संकलन इकाई में कैसे शामिल किया जा सकता है? – JaredPar

2

आप ऑपरेटर new के एक वैश्विक अधिभार करते हैं और इसे calloc() से कच्चे स्मृति हड़पने हो सकता था। इस तरह रचनाकारों को चलाने के लिए स्मृति को मिटा दिया जाता है इसलिए वहां कोई समस्या नहीं है।

कोई भी वर्ग जो अपने आप को नया ओवरराइड करता है, वह आपके विशेष calloc()-आधारित new नहीं प्राप्त करेगा, लेकिन तब उस वर्ग को स्वयं को सही ढंग से प्रारंभ करना चाहिए।

new और delete और सरणी संस्करणों दोनों ओवरराइड करने के लिए मत भूलना ...

कुछ की तरह:

#include <exception> // for std::bad_alloc 
#include <new> 
#include <stdlib.h> // for calloc() and free() 

void* operator new (size_t size) 
{ 
void *p=calloc(size, 1); 
if (p==0) // did allocation succeed? 
    throw std::bad_alloc(); 
return p; 
} 


void operator delete (void *p) 
{ 
free(p); 
} 

void* operator new[] (size_t size) 
{ 
void *p=calloc(size, 1); 
if (p==0) // did allocation succeed? 
    throw std::bad_alloc(); 
return p; 
} 

void operator delete[] (void *p) 
{ 
free(p); 
} 

ध्यान दें कि इन सरल संस्करण काफी वास्तव में वे क्या किया जाना चाहिए नहीं कर रहे हैं - new ऑपरेटर को new_handler (यदि कोई इंस्टॉल किया गया है) को कॉल करने वाले लूप में चलाना चाहिए और new_handler नहीं है तो केवल bad_alloc अपवाद फेंकना चाहिए। या ऐसा कुछ, मुझे इसे देखना और बाद में अपडेट करना होगा।

ओह, और आप no_throw संस्करण को भी ओवरराइड करना चाहेंगे।

+0

इस मामले में परिभाषित वर्चुअल विधियों वाले वर्गों के साथ क्या होता है? –

+1

कुछ भी असामान्य नहीं होता - कन्स्ट्रक्टर सामान्य रूप से चलता है। यह सिर्फ इतना है कि कन्स्ट्रक्टर पर कच्ची मेमोरी हमेशा काम करती है। –

0

यदि आप new का उपयोग करने का आग्रह नहीं करते हैं, तो आप बस वेक्टर: vector<char> buffer; buffer.resize(newsize); का उपयोग कर सकते हैं और सामग्री शून्य हो जाएगी।

0

हां।

int* p_scalar = new int(5);//Does not create 5 elements, but initializes to 5 

सरणियों के लिए आप memset की तरह कुछ का उपयोग कर सकते हैं। विंडोज़ के लिए ज़ीरोमेमरी या सिक्योरजेरो मेमरी का उपयोग करें।

संपादित करें: कृपया @ litb की पोस्ट देखें, वह दिखाता है कि आप ऊपर की तरह गैर प्रत्यक्ष प्रारंभिकरण का उपयोग करके सरणी के लिए 0 को कैसे प्रारंभ कर सकते हैं।

+0

सरणी के साथ प्रयास करें - यह काम नहीं करेगा (कम से कम आईएसओ सी ++ के लिए - शायद विस्तार के साथ कुछ कंपाइलर इसे अनुमति दे सकते हैं)। – Francis

0
class MyClass { 
    public: 
    void* operator new(size_t bytes) { 
     return calloc(bytes, 1); 
    } 
} 

और यदि आप चाहें तो वैश्विक नए ऑपरेटर को ओवरराइड कर सकते हैं।

0

आप कह सकते हैं:

vector <char> v(100, 0); 

जो नए का उपयोग कर 100 अक्षरों का एक सन्निहित सरणी बनाता है, और उन सब को शून्य करने के लिए initialises। इसके बाद आप वेक्टर के [] ऑपरेटर के साथ सरणी का उपयोग कर सकते हैं, या ऐसा करने से:

char * p = &v[0]; 
p[3] = 42; 

नोट यह भी आबंटित स्मृति मुक्त करने के लिए हटाने के कॉल करने के लिए होने से आप को मुक्त कर देते।

1

मैं मैक्रो का उपयोग:

#define newclear(TYPE) new(calloc(sizeof(TYPE), 1)) TYPE(); 

इसका इस्तेमाल करने की:

Whatever* myWhatever = newclear(Whatever); 

+0

से पहले मत भूलना # परिभाषित उल्लेख करने के लिए:।। डी (जाहिरा तौर पर इस साइट उसे निकाल देता –

+2

वहाँ वास्तव में स्रोत कोड के लिए एक विशेष स्वरूपण है कुछ भी आप मांगपत्र द्वारा चार रिक्त स्थान विशेष हाइलाइटिंग प्राप्त करेंगे (मेरा संपादन देखें)। –

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