2011-03-06 10 views
7
# include <stdio.h> 
# include <stdbool.h> 
# include <string.h> 
# include <stdlib.h> 

int main() 
{ 
    char * buffer; 
    buffer = malloc (2); 

    if (buffer == NULL){ 
    printf("big errors"); 
    } 
    strcpy(buffer, "hello"); 
    printf("buffer is %s\n", buffer); 
    free(buffer); 
    return 0; 
} 

मैंने पॉइंटर/चार बफर को स्मृति के 2 बाइट आवंटित किए हैं, फिर भी यदि मैं इसे "हैलो" असाइन करता हूं, तो यह मुझे अभी भी प्रिंट करता है, बिना किसी त्रुटि के। संकलक मुझे एक त्रुटि क्यों नहीं बताता है कि आवंटित पर्याप्त स्मृति नहीं है? मैंने कुछ प्रश्न पढ़े जो पूछते हैं कि कितनी मेमोरी malloc वास्तव में आवंटित करती है लेकिन मुझे ठोस जवाब नहीं मिला। free फ़ंक्शन को यह नहीं पता होना चाहिए कि buffer पर कितनी मेमोरी आवंटित की गई है?मॉलोक -> कितनी मेमोरी आवंटित की गई है?

+0

आप भाग्यशाली थे कि आपने 4 अतिरिक्त बाइट्स द्वारा मेमोरी के किसी भी महत्वपूर्ण टुकड़े को ओवरराइड नहीं किया है, जो आपके पास नहीं है; आप हर बार ऐसे भाग्यशाली नहीं होंगे, और इससे दुर्घटना हो जाएगी। अंत में – holex

उत्तर

14

संकलक नहीं जानता है। यह सी malloc का आनंद और आतंक रनटाइम से संबंधित है। सभी कंपाइलर्स जानते हैं कि आपने यह कहा है कि यह एक शून्य * देता है, यह नहीं पता कि कितना, या कितना strcpy कॉपी करने जा रहा है।

उपकरण valgrind की तरह इन त्रुटियों के कुछ पता लगाने। अन्य प्रोग्रामिंग भाषाएं पैर में खुद को शूट करना कठिन बनाती हैं। नहीं सी

+2

लेकिन अन्य भाषाओं में, जब आप पैर में खुद को गोली मारते हैं, तो यह आपके पूरे पैर को उड़ा देता है! – fouronnes

1

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

1

क्यों संकलक मुझे वहाँ नहीं है पर्याप्त स्मृति आवंटित कह एक त्रुटि दिखा सकते हैं नहीं करता है?

C स्मृति आप नहीं करना चाहिए का उपयोग करने से ब्लॉक नहीं करता। आप उस स्मृति का उपयोग कर सकते हैं, लेकिन यह खराब है और परिणामस्वरूप अपरिभाषित व्यवहार में है। आप ऐसी जगह पर लिख रहे हैं जहां आपको नहीं करना चाहिए। यह प्रोग्राम सही ढंग से चलने के रूप में दिखाई दे सकता है, लेकिन बाद में क्रैश हो सकता है। यह UB है। आप नहीं जानते कि क्या हो सकता है।

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

मैं सवाल है कि पूछना कितनी स्मृति malloc वास्तव में आवंटित की जाँच करने के लिए कैसे की एक जोड़ी पढ़ा लेकिन मैं एक ठोस जवाब नहीं मिला। 'मुफ़्त' समारोह पता करने के लिए कितनी स्मृति वास्तव में 'बफ़र' के लिए आवंटित किया गया है नहीं करना चाहिए?

malloc() बिट पैडिंग के कारण से अधिक स्मृति आवंटित कर सकता है।

अधिक: http://en.wikipedia.org/wiki/Data_structure_alignment

free() मुक्त रों ठीक उसी राशि है जो आप malloc() साथ आवंटित है, लेकिन यह के रूप में स्मार्ट के रूप में आपको लगता है नहीं है। उदाहरण के लिए:

int main() 
{ 
    char * ptr = malloc(10); 
    if(ptr) 
    { 
     ++ptr; // Now on ptr+1 
     free(ptr); // Undefined Behaviour 
    } 
} 

आप चाहिए हमेशा free() एक सूचक जो पहले खंड के लिए अंक। free(0) करना सुरक्षित है।

+0

टाइपो? – bmargulies

+0

@bmaurgulies, हाँ क्षमा करें। तय की। – Muggen

1

आप बफर आप आवंटित के अंत अतीत में लिखा है।नतीजा अपरिभाषित व्यवहार है। सही विकल्पों वाले कुछ रन टाइम लाइब्रेरीज़ में कम से कम कुछ ऐसी समस्याएं निदान करने की क्षमता होती है, लेकिन सभी नहीं करते हैं, और यहां तक ​​कि जो लोग केवल रन-टाइम पर ऐसा करते हैं, और आमतौर पर केवल सही विकल्पों के साथ संकलित होने पर ही करते हैं।

4

कोई उत्पादन malloc() कार्यान्वयन आपको आवंटित किए गए पिछले कार्यों को लिखने से रोकने से रोकना चाहिए। यह माना जाता है कि यदि आप 123 बाइट आवंटित करते हैं, तो आप आवंटित किए गए सभी से कम या कम उपयोग करेंगे। दक्षता के लिए malloc(), यह मानना ​​है कि एक प्रोग्रामर अपने पॉइंटर्स का ट्रैक रखने जा रहा है।

स्मृति का उपयोग करना जो आपने स्पष्ट रूप से और सफलतापूर्वक malloc() से अपरिभाषित व्यवहार देने के लिए कहा है। आपने n बाइट्स के लिए कहा होगा लेकिन malloc() बाइट संरेखण के लिए अनुकूलन कार्यान्वयन के कारण n + x मिला है। या आप ब्लैक होल पर लिख सकते हैं। आप कभी नहीं जानते, यही कारण है कि यह अपरिभाषित व्यवहार है।

कहा जा रहा है ...

लेकिन इन जैसे आप अगर आप एक garbage collected variety का उपयोग किया जा मानक malloc() सुविधा के एवज में इस्तेमाल किया जा करने की जरूरत है malloc() कार्यान्वयन दे कि आप statistics and debugging में बनाया गया है,।

मैंने एलडी_PRELOAD के लिए सख्ती से डिजाइन किए गए वेरिएंट भी देखे हैं जो एक फ़ंक्शन का पर्दाफाश करते हैं ताकि आप कम से कम एक शून्य पॉइंटर को तर्क के रूप में कॉलबैक परिभाषित कर सकें। वह तर्क एक संरचना की अपेक्षा करता है जिसमें सांख्यिकीय डेटा शामिल है। electric fence जैसे अन्य टूल बस आपके प्रोग्राम को सटीक निर्देश पर रोक देंगे जिसके परिणामस्वरूप अमान्य ब्लॉक तक पहुंच या पहुंच हो गई है। @ आर के रूप में .. टिप्पणियों में बताता है, यह डीबगिंग के लिए बहुत अच्छा है लेकिन बेहद अक्षम है।

सब ईमानदारी में या (के रूप में वे कहते हैं) 'दिन के अंत में' - यह इस मामले में Valgrind और इससे संबंधित उपकरण (massif) के रूप में एक ढेर प्रोफाइलर इस तरह के उपयोग करने के लिए बहुत आसान है जो आप काफ़ी दे देंगे जानकारी की। इस विशेष मामले में, वालग्रिंड ने स्पष्ट रूप से बताया होगा - आपने आवंटित सीमा से पहले लिखा था। ज्यादातर मामलों में, हालांकि यह जानबूझकर नहीं है, एक अच्छा प्रोफाइलर/त्रुटि डिटेक्टर अमूल्य है।

  • समय मुद्दों जबकि एक प्रोफाइलर के तहत चल रहा है (लेकिन उन किसी भी समय रोक दिया जाता है malloc() करने के लिए कॉल आम हैं):

    एक प्रोफाइलर का उपयोग करना हमेशा संभव नहीं के कारण है।

  • प्रोफाइलर अपने मंच/मेहराब लिए उपलब्ध नहीं है
  • डीबग डेटा (एक प्रवेश malloc() से) कार्यक्रम का एक अभिन्न हिस्सा

हम पुस्तकालय है कि मैं HelenOS में जुड़े हुए का एक संस्करण इस्तेमाल किया जाना चाहिए (मुझे यकीन नहीं है कि वे अभी भी इसका उपयोग कर रहे हैं) थोड़ी देर के लिए, क्योंकि वीएमएम में डिबगिंग पागलपन के कारण जानी जाती थी।

फिर भी, भविष्य परिणामों के बारे में कठिन लगता है कि जब प्रतिस्थापन में एक बूंद पर विचार जब यह malloc() सुविधा आप लगभग हमेशा क्या उपयोग करने के लिए प्रणाली जहाजों चाहते की बात आती है।

+0

वास्तव में एक 'malloc' कार्यान्वयन आपको ऐसा करने से बचा सकता है, अगर यह किसी पृष्ठ के अंतिम 'N' बाइट्स के लिए' एन' बाइट्स 'की व्यवस्था करता है, और इसके बाद एक गार्ड पेज रखता है ... :-) यह है वास्तव में अक्षम है लेकिन यह एक अच्छा डीबगिंग कार्यान्वयन है। –

+0

@ आर .. स्पष्टता के लिए मेरा जवाब अपडेट किया गया, मैं इस संदर्भ में बात कर रहा था कि 'सिस्टम malloc() मुझे ऐसा करने से क्यों रोकता है?' –

0

मॉलोक -> कितनी मेमोरी आवंटित की गई है?

जब आप malloc का उपयोग करके स्मृति आवंटित करते हैं।सफलता पर यह स्मृति आवंटित करता है और डिफ़ॉल्ट आवंटन 128k है। मॉलोक के लिए पहले कॉल आपको 128k देता है।

आपने जो अनुरोध किया है वह buffer = malloc (2); है हालांकि आपने 2 बाइट्स का अनुरोध किया था। यह 128k आवंटित किया गया है।

strcpy(buffer, "hello"); आवंटित 128k खंड ने आपके अनुरोध को संसाधित करना शुरू कर दिया। "हैलो" स्ट्रिंग इसमें फिट हो सकती है।

यह पीजीएम आपको स्पष्ट कर देगा।

int main() 
{ 
int *p= (int *) malloc(2);---> request is only 2bytes 

p[0]=100; 
p[1]=200; 
p[2]=300; 
p[3]=400; 
p[4]=500; 

int i=0; 
के लिए

(; मैं < 5; i ++, पी ++) enter code here printf ("% d \ t", * p);

} 

malloc पर पहली बार कॉल करें। यह 128k ---> से आवंटित करता है जिससे कि यह आपके अनुरोध (2 बाइट्स) को संसाधित करता है। स्ट्रिंग "हैलो" इसमें फिट हो सकती है। फिर जब malloc को दूसरी कॉल यह 128k से आपके अनुरोध को संसाधित करता है।

128k से परे यह mmap इंटरफ़ेस का उपयोग करता है। आप मॉलोक के मैन पेज का उल्लेख कर सकते हैं।

0

कोई संकलक/प्लेटफार्म स्वतंत्र तरीका है कि यह पता लगाने के लिए कि वास्तव में कितना मेमोरी मॉलोक आवंटित किया गया है। malloc सामान्य आवंटन थोड़ा अधिक आप इसे पूछने में के लिए यहाँ देखेंगे:

http://41j.com/blog/2011/09/finding-out-how-much-memory-was-allocated/

लिनक्स पर आप पता लगाने के लिए आप कितनी स्मृति का उपयोग कर सकते malloc_usable_size उपयोग कर सकते हैं। मैकोज़ और अन्य बीएसडी प्लेटफार्मों पर आप malloc_size का उपयोग कर सकते हैं। उपरोक्त लिंक में इन दोनों तकनीकों का पूरा उदाहरण है।

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