2010-10-03 10 views
29

जब हम realloc() के माध्यम से स्मृति को पुन: आवंटित करते हैं, तो पिछली सामग्री अधिक लिखित हैं? मैं एक ऐसा प्रोग्राम बनाने की कोशिश कर रहा हूं जो हर बार जब हम डेटा दर्ज करते हैं तो स्मृति को पुन: आवंटित करता है।क्या रीयलोक पुरानी सामग्री को ओवरराइट करता है?

कृपया मुझे रीयलोक के माध्यम से स्मृति आवंटन के बारे में बताएं, क्या यह उदाहरण के लिए संकलक निर्भर है?

उत्तर

67

पुरानी सामग्री के बारे में चिंता न करें।

उपयोग करने के लिए realloc पुनः आबंटन के लिए एक विशिष्ट सूचक का उपयोग करना है सही तरीका, परीक्षण है कि सूचक और, अगर सब कुछ ठीक काम किया, वर्ष सूचक

int *oldpointer = malloc(100); 

/* ... */ 

int *newpointer = realloc(oldpointer, 1000); 
if (newpointer == NULL) { 
    /* problems!!!!         */ 
    /* tell the user to stop playing DOOM and retry */ 
    /* or free(oldpointer) and abort, or whatever */ 
} else { 
    /* everything ok                 */ 
    /* `newpointer` now points to a new memory block with the contents of oldpointer */ 
    /* `oldpointer` points to an invalid address          */ 
    oldpointer = newpointer; 
    /* oldpointer points to the correct address        */ 
    /* the contents at oldpointer have been copied while realloc did its thing */ 
    /* if the new size is smaller than the old size, some data was lost  */ 
} 

/* ... */ 

/* don't forget to `free(oldpointer);` at some time */ 
+20

+1: डी – zeboidlund

+0

'oldpointer = newpointer; '' newpointer' को मुक्त किया जाना चाहिए या मुझे इसे रखना चाहिए? –

+5

'oldpointer = newpointer के बाद; 'दोनों पॉइंटर्स स्मृति के उसी क्षेत्र को इंगित करते हैं। 'मुक्त (नया सूचक) करना; '' मुक्त (पुराना पॉइंटर) जैसा ही होगा; '। आप किसी भी तरह से 'newpointer' के साथ गड़बड़ नहीं करना चाहते हैं: बस भूल जाओ कि यह मौजूद है। – pmg

11

यह मौजूदा सामग्री को ओवरराइट किए बिना पहले से आवंटित स्मृति को बढ़ाता है, या (यदि यह बढ़ने में असमर्थ है) तो यह एक अलग स्थान पर नई बड़ी मेमोरी आवंटित करता है और पिछली मेमोरी से मौजूदा मेमोरी को नई मेमोरी में कॉपी करता है।

+0

और सूचक को बदलने भी करने के लिए बात करने के लिए किया जाता है नया स्थान? –

+0

realloc एक नया पॉइंटर मान देता है, जिसका मान पुराना सूचक मान जैसा ही हो सकता है या नहीं हो सकता है, और जिसे आप अपने पिछले सूचक मूल्य को ओवरराइट करने के लिए उपयोग करना चाहिए: उदा।'ptr = realloc (ptr, new_size);' – ChrisW

+3

यदि रीलॉक विफल हो जाता है, तो आपके 'ptr' अंक को नल और पुराने पीआरटी खो जाता है (' स्मृति रिसाव 'पढ़ें) – pmg

5

यह बताने के लिए कि तुम क्या कह रहे हैं बहुत मुश्किल है, लेकिन यदि आप पूछ रहे हैं कि क्या आप "पुराने सामग्री" realloc के लिए पारित पुराने पते पर पढ़ सकते हैं, इस सवाल का जवाब कोई है। कुछ मामलों में, आपको वहां भाग या सभी पुरानी सामग्री मिल सकती है, लेकिन जब तक realloc आपके द्वारा पारित उसी सूचक को वापस नहीं लौटाता है, तो पुराने सूचक का कोई भी उपयोग अपरिभाषित व्यवहार है।

यदि आप केवल यह पूछ रहे हैं कि पुरानी सामग्री realloc द्वारा लौटाए गए नए पते पर संरक्षित की जाएगी, तो उत्तर हाँ (पुराने आकार और नए आकार के न्यूनतम तक) है।

9

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

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

यदि आप एक प्रतिलिपि चाहते हैं तो एक नया मॉलोक करें और memcpy का उपयोग करें।

कार्यान्वयन के लिहाज से, जब आप वृद्धि आकार के realloc कहते हैं, इन बातों में से एक हो सकता है:

  • एक नया ब्लॉक आवंटित किया जाता है और पुराने स्मृति की सामग्री को कॉपी, पुराने ब्लॉक है मुक्त, नया सूचक वापस आ गया है।
  • यदि ब्लॉक के बाद क्षेत्र आवंटित नहीं किया गया है, तो मौजूदा ब्लॉक बढ़ाया जा सकता है और एक ही सूचक वापस लौटाया जा सकता है।

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

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