2008-10-24 7 views
9

मैं एक असाइनमेंट के लिए पूंछ को लागू करने पर काम कर रहा हूं। मुझे यह सही तरीके से काम कर रहा है, हालांकि मुझे यादृच्छिक समय पर मुफ्त में त्रुटि मिल रही है।मॉलोक त्रुटि: मुक्त ऑब्जेक्ट के लिए गलत चेकसम

मैं इसे देखने के लिए नहीं देख सकता, इसे पैटर्न के नीचे या इसके अलावा कुछ भी सुसंगत है।

उदाहरण के लिए यदि मैं अपने प्रोग्राम को "tail -24 test.in" के रूप में कॉल करता हूं तो मुझे कई रनों पर एक ही पंक्ति में गलत चेकसम त्रुटि मिल जाएगी। हालांकि, अलग-अलग फाइलों और यहां तक ​​कि प्रिंट करने के लिए लाइनों की अलग-अलग संख्याओं के साथ मैं त्रुटियों के बिना वापस आऊंगा।

इस मुद्दे को ट्रैक करने के तरीके पर कोई विचार, मैं इसे बिना किसी लाभ के घंटों तक डीबग करने का प्रयास कर रहा हूं।

lines = (char**) malloc(nlines * sizeof(char *)); 

void insert_line(char *s, int len){ 

    printf("\t\tLine Number: %d Putting a %d line into slot: %d\n",processed,len,slot); 
    if(processed > numlines -1){//clean up 
    free(*(lines+slot)); 
    *(lines + slot) = NULL; 
    } 
    *(lines + slot) = (char *) malloc(len * sizeof(char)); 
    if(*(lines + slot) == NULL) exit(EXIT_FAILURE); 
    strcpy(*(lines+slot),s); 
    slot = ++processed % numlines; 
} 
+0

स्लॉट 0 या 1 आधारित है? स्लॉट कभी भी nlines-1 से अधिक नहीं है, सही? – Dre

+0

सही मॉड्यूलस स्वचालित रूप से इसे 0 – None

+0

पर वापस ले जाता है जो आप किस कंपाइलर और डीबगर का उपयोग कर रहे हैं? उस पर निर्भर करते हुए, वे आपकी समस्या को डीबग करने में कुछ सहायता प्रदान कर सकते हैं। –

उत्तर

7

आपका दिनचर्या आवंटित लाइन बफर से परे लिख रहा है।

एक तर्क के रूप में पारित लाइन का आकार (यानी "लेन") में शायद एनयूएल टर्मिनेटर शामिल नहीं है। जब आप लाइन की प्रतिलिपि बनाने के लिए मॉलोक को कॉल करते हैं (यानी ")" आपको स्ट्रिंग टर्मिनेटर के लिए अतिरिक्त बाइट आवंटित करने की आवश्यकता होती है:

*(lines + slot) = (char *) malloc((len + 1) * sizeof(char)); 
+3

यह उत्तर कैसे स्वीकार किया गया? इस उत्तर को पोस्ट करने से एक दिन पहले, मूल पोस्टर ने मेरे जवाब पर टिप्पणी की और कहा, "कॉलिंग फ़ंक्शन द्वारा शून्य को जिम्मेदार माना जाता है।" –

0

NLINES करो और numlines एक ही मूल्य है:

लाइनों था malloc के रूप में एक चार के रूप में परिभाषित किया गया है ** और:

यहाँ अपमानजनक कोड नहीं है?

क्या दूसरे पैरामीटर में लंबाई पारित करते समय insert_line के कॉलर पिछला एनयूएल के लिए कमरे की अनुमति देता है?

+0

हां, nlines और numlines एक ही मूल्य हैं। वास्तव में लाइन की घोषणा, कहीं और होती है। कॉलिंग फ़ंक्शन द्वारा शून्य को जिम्मेदार माना जाता है। – None

0

मुझे यकीन है कि यह संबंधित है नहीं कर रहा हूँ, लेकिन इन दो पंक्तियों में मेरे लिए संदिग्ध लगता है:

*(lines + slot) = (char *) malloc(len * sizeof(char)); 
    if((lines + slot) == NULL) exit(EXIT_FAILURE); 

आप पहली बार lines[slot] को malloc की वापसी आवंटित और फिर आप (lines+slot) जाँच, अगर दूसरी स्थिति शून्य था, तो आप के लिए किया था एक पूर्ण सूचक dereference!

यदि लाइन [स्लॉट] (आपकी * (रेखाएं + स्लॉट)) शून्य नहीं है, तो आप स्मृति को रिसाव करेंगे जब आप malloc() के परिणाम को आवंटित करेंगे।

मुझे लगता है कि lineschar * रेखाएं [] `और स्लॉट अनुमत सीमा के भीतर है!

0

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

*(lines + slot) = some value 
if((lines + slot) == NULL) then die 
should be 
if(*(lines + slot) == NULL) then die 
+0

अरे, आपने इस स्रोत को संपादित करते समय अपना स्रोत कोड संपादित किया था। उस स्थिति में आपकी बग शायद प्रोग्राम के किसी अन्य भाग में है जिसे आपने अभी तक संपादित नहीं किया है ... –

+0

मैंने वास्तव में इसे पहले ही तय कर दिया था ... ऐसा नहीं है कि मेरी त्रुटि malloc – None

3

आप लगातार विशिष्ट इनपुट पैरामीटर के साथ समस्या को पुन: कर सकते हैं, तो आप इस तरह डिबग चाहिए:

  • सटीक मुक्त है कि समस्या का कारण बनता है के लिए सबसे पहले डिबग।
  • तब पता लगाएं कि जब स्मृति को मुक्त किया जा रहा है तो malloced था।
  • अगला, उस स्थान पर डीबग करें जहां स्मृति malloc'ed है।
  • मेमोरी व्यूअर मेमोरी के आवंटित ब्लॉक में खोजें। ब्लॉक की शुरुआत और अंत दोनों नोट करें। ब्लॉक के ठीक पहले और बस गार्ड ब्लॉक नामक एक विशेष मूल्य है।
  • अब स्मृति को मुक्त होने तक कोड के माध्यम से कदम उठाएं। किसी बिंदु पर आपके कोड को गार्ड ब्लॉक को गलती से ओवरराइट करना चाहिए। यह अपमानजनक कथन है।

ध्यान दें कि समस्या आपके प्रोग्राम के पूरी तरह से अलग हिस्से में बहुत अच्छी तरह से हो सकती है। भले ही यह मुफ्त है कि त्रुटि की रिपोर्ट कर रहा है, कोड जो ब्लॉक ब्लॉक को ओवरराइट करता है वह कहीं भी हो सकता है।

+0

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

+0

कुछ अन्य कोड इसकी आवंटित स्मृति और आपके ब्लॉक के चारों ओर गार्ड मानों के बाहर लिख रहे हैं।यही कारण है कि आपको मॉलोक और मुफ्त के बीच सभी कोडों को पार करने की आवश्यकता है। कुछ बिंदु पर कुछ कोड गार्ड मानों में से एक को ओवरराइट कर देंगे। –

1

मेरा पहला सवाल यह है कि आप लेन की गणना कैसे करते हैं? क्या यह सिर्फ strlen है या इसमें \ 0 टर्मिनेटर के लिए कमरा शामिल है? मुझे लगता है कि आप अपने strcpy में अपने आवंटन overshooting हो सकता है। शब्द सीमाओं पर बुरा व्यवहार होता है और यादृच्छिक दिखाई देता है। साथ ही, यह सुनिश्चित करने के लिए जांचें कि आपके स्रोत स्ट्रिंग को समाप्त कर दिया गया है। यदि आपने पढ़ने की ओर गलती की है और उन्हें समाप्त नहीं किया है। फिर strcpy यादृच्छिक रूप से चीजों को ओवरराइट कर सकता है।

*(lines + slot) = (char *) malloc(len * sizeof(char)); 
    if(*(lines + slot) == NULL) exit(EXIT_FAILURE); 
    strcpy(*(lines+slot),s); 

शायद कोशिश:

lines[slot] = (char *) malloc((len + 1) * sizeof(char)); 
    if(lines[slot] == NULL) exit(EXIT_FAILURE); 
    if(strlen(s) <= len){ 
    strcpy(lines[slot],s); 
    } 
    else{ 
    /* do something else... */ 
    } 

सामान्य रूप के संदर्भ में, मैं भी आपको कुछ शैलीगत परिवर्तन करने के लिए पूरी बात में थोड़ा और अधिक पठनीय बनाने के लिए, की सलाह देते हैं पालन करने के लिए आसान है और प्रतिरोधी त्रुटियों के लिए।

सूचक अंकगणित वैध और मजेदार है, लेकिन मुझे लगता है कि अपने इरादे को थोड़ा और स्पष्ट है अगर आप की तरह सरणी फार्म का उपयोग करें:

free(lines[slot]); 
lines[slot] = NULL; 
बजाय

free(*(lines+slot)); 
*(lines + slot) = NULL; 

मैं भी सलाह देते हैं आप कम statics का उपयोग करने के लिए। डेटा संरचना में उनके माध्यम से उनके लिए काफी आसान है और उन्हें अपने एक्सेसर्स और म्यूटेटर में पास कर दें। यह और अधिक स्पष्ट जहां कार्रवाई हो रहा है हो जाता है आप की तरह काम करने से रोकता है:

static int numlines = 0; 
void insert_line(char *s, int len){ 
    int numlines = 5; 

जहां देखते हुए मुद्दों है कि बस डिबग करने के लिए दुखी हैं लागू कर सकते हैं।