2012-11-24 62 views
12

मैं एक संपीड़न एल्गोरिथ्म को लागू किया है (Huffman कोडिंग का प्रयोग करके) जो नोड्स के एक प्राथमिकता कतार (एक struct मैं परिभाषित) का उपयोग करता है में ठीक काम करता है। अब, जब मैं सिर्फ लिनक्स में या दृश्य स्टूडियो में कोड चलाता हूं, तो सब कुछ ठीक काम करता है। जब मैं विजुअल स्टूडियो में मेमोरी लीक की जांच करता हूं, तो कोई भी नहीं दिया जाता है।वेलग्रिंड: आकार 4 की अवैध पढ़ा -> SIGSEGV, valgrind बिना और दृश्य स्टूडियो

समस्या अब है, जब मैं अपने प्रोग्राम का विश्लेषण करने के लिए valgrind का उपयोग करता हूं, यह सिग्नल 11 (sigsegv) के साथ समाप्त होता है। पहली त्रुटि का सामना मिनट में हटाए गए विधि में 'आकार 4 का अमान्य पढ़ने' है। इसके बाद अन्य त्रुटियां हैं: एड्रेस 453 मुक्त आकार के ब्लॉक के अंदर 0 बाइट्स है, आकार 4 का अमान्य लेखन, अमान्य मुफ्त, हटाएं या फिर से चलाएं।

किसी को भी मुझे मैं संभवतः त्रुटि की किस तरह कर सकता था के बारे में सलाह दे सकते हैं? मैं घंटों तक इंटरनेट खोज रहा हूं, लेकिन मुझे यह नहीं मिल रहा है कि मैं क्या कर रहा हूं (विशेष रूप से जब यह वाल्ग्रिंड का उपयोग नहीं करता है)। या युक्तियाँ कैसे डिबग करें और पता लगाएं कि पढ़ने में त्रुटि क्या हो रही है।

कई धन्यवाद!

अगर कोई व्यक्ति इसकी समीक्षा करना चाहेगा तो कोड यहां है, लेकिन मुझे लगता है कि इस विशिष्ट कोड में केवल गोता लगाने के लिए इतना आसान नहीं है। > हर बार 2 कम से कम नोड्स हटा सकते हैं और दोनों का योग वापस जोड़ने के रूप में -

हिस्सा है जहाँ मैं Huffman हिस्सा कार्य करें:

मेरा अनुमान है कि यह कोड की प्राथमिकता कतार के साथ कुछ है एक नोड

void insert_node(priority_queue* p_queue, node* x){ 
    int i = p_queue->size; 
    if(i == 0){ 
     p_queue->queue = (node**) malloc(sizeof(node*)); 
    } 
    else{ 
     p_queue->queue = (node**) realloc(p_queue->queue,sizeof(node*)*(p_queue->size+1)); 
    } 
    p_queue->queue[p_queue->size] = x; 

    while(i>=0 && p_queue->queue[i]->amount < p_queue->queue[(i-1)/2]->amount){ 
     node* temp = p_queue->queue[i]; 
     p_queue->queue[i] = p_queue->queue[(i-1)/2]; 
     p_queue->queue[(i-1)/2] = temp; 
     i = (i-1)/2; 
    } 
    p_queue->size++; 
} 

node* delete_min(priority_queue* p_queue){ 
    node** queue = p_queue->queue; 
    node* min = queue[0]; 

    if(p_queue->size>1){ 
     int r = 0; 
     int current = 1; //left child of root 

     queue[0] = queue[p_queue->size-1]; 
     queue = (node**) realloc(queue,sizeof(node*)*(--p_queue->size)); 
     while(current < p_queue->size){ 
      //in case of 2 children, check if current needs to be right or left child 
      if(current < p_queue->size-1 && queue[current] > queue[current+1]){ 
       current++; 
      } 
      if(queue[current] < queue[r]){ 
       node* temp = queue[r]; 
       queue[r] = queue[current]; 
       queue[current] = temp; 

       r = current; 
       current = 2 * current; 
      } 
      else{ 
       break; 
      } 
      current++; 
     } 
    } 
    else{ 
     free(queue); 
     p_queue->size--; 
    } 
    return min; 
} 

संपादित करें:

while(queue->size > 1){ 
    node* n1 = delete_min(queue); 
    node* n2 = delete_min(queue); // all the errors are encountered in this call 
    node* temp = (node*) calloc(sizeof(node),1); 
    temp->amount = n1->amount + n2->amount; 
    insert_node(queue,temp); 
    n1->parent = temp; 
    n2->parent = temp; 
    temp->left = n1; 
    temp->right = n2; 
} 

यहाँ है प्राथमिकता कतार के लिए delete_min और insert_node तरीके हैं जोड़ा valgrind उत्पादन:

Invalid read of size 4 
==1893== at 0x80498E0: delete_min (huffman.c:331) 
==1893== by 0x80492DA: huffman_encode (huffman.c:196) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 
==1893== Address 0x441d9a8 is 0 bytes inside a block of size 452 free'd 
==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==1893== by 0x8049922: delete_min (huffman.c:335) 
==1893== by 0x80492CC: huffman_encode (huffman.c:195) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 
==1893== 
==1893== Invalid read of size 4 
==1893== at 0x8049901: delete_min (huffman.c:333) 
==1893== by 0x80492DA: huffman_encode (huffman.c:196) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 
==1893== Address 0x441db64 is 444 bytes inside a block of size 452 free'd 
==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==1893== by 0x8049922: delete_min (huffman.c:335) 
==1893== by 0x80492CC: huffman_encode (huffman.c:195) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 
==1893== 
==1893== Invalid write of size 4 
==1893== at 0x8049906: delete_min (huffman.c:333) 
==1893== by 0x80492DA: huffman_encode (huffman.c:196) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 
==1893== Address 0x441d9a8 is 0 bytes inside a block of size 452 free'd 
==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==1893== by 0x8049922: delete_min (huffman.c:335) 
==1893== by 0x80492CC: huffman_encode (huffman.c:195) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 
==1893== 
==1893== Invalid free()/delete/delete[]/realloc() 
==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==1893== by 0x8049922: delete_min (huffman.c:335) 
==1893== by 0x80492DA: huffman_encode (huffman.c:196) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 
==1893== Address 0x441d9a8 is 0 bytes inside a block of size 452 free'd 
==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==1893== by 0x8049922: delete_min (huffman.c:335) 
==1893== by 0x80492CC: huffman_encode (huffman.c:195) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 
==1893== 
==1893== Invalid read of size 4 
==1893== at 0x8049A0E: delete_min (huffman.c:337) 
==1893== by 0x80492DA: huffman_encode (huffman.c:196) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 
==1893== Address 0x0 is not stack'd, malloc'd or (recently) free'd 
==1893== 
==1893== 
==1893== Process terminating with default action of signal 11 (SIGSEGV) 
==1893== Access not within mapped region at address 0x0 
==1893== at 0x8049A0E: delete_min (huffman.c:337) 
==1893== by 0x80492DA: huffman_encode (huffman.c:196) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 

लाइन 331 की delete_min में लाइन है: नोड * मिनट = कतार [0];

संपादित करें:

समस्या अब हल हो गया है। स्वीकार्य उत्तर में, कारण क्यों समझाया गया है। हटाए गए मान को सही ढंग से असाइन करना, delete_min में सभी मुद्दों को हल किया गया।

//realloc queue and assign new value to local queue var 
p_queue->queue = (node**) realloc(queue,sizeof(node*)*(--p_queue->grootte)); 
queue = p_queue->queue; 
+0

'जबकि ((2 * i) +2 < p_queue-> आकार -1 1 <- आप जल्दी बंद हो रहे हैं। यदि' 2 * i + 2 == आकार -1 ', बायां बच्चा अभी भी कतार में मौजूद है, लेकिन आप इसे जांचें नहीं। –

+0

delete_min में कोड वास्तव में स्पष्ट नहीं था, इसलिए मैं इसे और अधिक स्पष्ट करने के लिए पुनः लिखता हूं (नया कोड देखें)। प्रोग्राम का उपयोग करने से अभी भी काम करता है, लेकिन इसे valgrind के साथ जांचते समय, वही त्रुटि अभी भी दिखाई दे रहा है। मुझे अभी भी यह नहीं पता कि यह क्यों चल रहा है, लेकिन यह वाल्ग्रिंड का उपयोग करते समय विफल रहता है। – HaS

उत्तर

13

मैं आपको पहली त्रुटि समझाऊंगा।

==1893== Invalid read of size 4 
==1893== at 0x80498E0: delete_min (huffman.c:331) 
==1893== by 0x80492DA: huffman_encode (huffman.c:196) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 

लाइन 331 पर, आप शायद एक (अहस्ताक्षरित) पूर्णांक पढ़ रहे हैं, स्मृति आप अपने खुद के कार्यक्रम के लिए आवंटित नहीं किया है के एक भाग में।

==1893== Address 0x441d9a8 is 0 bytes inside a block of size 452 free'd 
==1893== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==1893== by 0x8049922: delete_min (huffman.c:335) 
==1893== by 0x80492CC: huffman_encode (huffman.c:195) 
==1893== by 0x8049DDE: encode_file (main.c:94) 
==1893== by 0x8049BBE: main (main.c:32) 
==1893== 

इस भाग स्मृति का हिस्सा आप को पढ़ने के लिए करने की कोशिश की के बारे में अधिक जानकारी देता है। यह कहता है कि आप पहले से ही स्मृति का उपयोग कर चुके हैं, लेकिन reallox इसे मुक्त कर दिया। इसका मतलब है कि आप पुराने पॉइंटर से स्मृति के एक हिस्से में पढ़ रहे हैं जिसे आपने पुनः आवंटित किया है।

आपको यह सुनिश्चित करना चाहिए कि आप पॉइंटर रीयलॉक रिटर्न का उपयोग करें, न कि पुराना।

बाहरी वाल्ग्रिंड चलाने के दौरान यह क्रैश नहीं होता है, यह है कि ज्यादातर समय, स्मृति का एक ही हिस्सा realloc द्वारा आवंटित किया जाएगा। तो सूचक एक ही रहता है, और जैसे आपका कोड काम करेगा। हालांकि, कभी-कभी, realloc स्मृति के हिस्से को स्थानांतरित करने का निर्णय लेगा, और फिर आपका कोड क्रैश हो जाएगा। Valgrind इस के लिए आपको चेतावनी देने की कोशिश कर रहा है।

जब आप लौटाए गए पॉइंटर का उपयोग कर रहे हों तो शेष त्रुटियों को हल किया जाएगा।

+0

वास्तव में यह मामला था। मैंने अपनी स्थानीय परिवर्तनीय कतार में पुनर्वित्तित कतार सौंपा, लेकिन मुझे इसे अपनी संरचना p_queue की कतार में असाइन करना चाहिए था। यह वास्तव में सभी अन्य त्रुटियों को हल करता है और अब मैं शुद्ध हूं! आपका बहुत बहुत धन्यवाद! – HaS

3

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

संपादित करें: सबसे स्पष्ट त्रुटि, segfault, जगह है जहाँ आप डिबगिंग शुरू कर देना चाहिए। इस लाइन में विफल रहता है:

while((2*i)+2 < p_queue->grootte-1 && (queue[i]->amount > queue[(2*i)+1]->amount || queue[i]->amount > queue[(2*i)+2]->amount)){ 

शायद क्योंकि queue शून्य है। यह सब क्यों है? शायद क्योंकि realloc कुछ भी आवंटित नहीं किया था। यह कुछ भी आवंटित क्यों नहीं किया? क्योंकि या तो आप स्मृति (संभावना नहीं) से बाहर भाग या क्योंकि तुम आकार 0. के बारे में कुछ आवंटित करने के लिए करने की कोशिश की (realloc के विवरण के लिए http://www.cplusplus.com/reference/cstdlib/realloc/ देखें)। आप आकार 0 का अनुरोध कैसे कर सकते हैं? यदि p_queue->size-1 0.

+0

मैंने अब वाल्ग्रिंड आउटपुट जोड़ा है! अजीब चीज यह है कि मैं केवल huffman_encoding पूरा होने के बाद ही मुक्त नोड्स करता हूं। इसलिए मैं ' टी यह क्यों नहीं है कि यह पहले से ही delete_min में शिकायत करता है जबकि मैंने कुछ भी मुक्त नहीं किया है। – HaS

+0

संशोधित पोस्ट देखें। रास्ते में स्टैक ओवरफ़्लो में आपका स्वागत है! –

+0

धन्यवाद :) मैंने यह भी सोचा कि समस्या हो सकती है, लेकिन मैं बदल गया (delete_min का संपादन कोड देखें)। अब क्यूई मुक्त हो गया है जब पूर्व आकार 1 था (और आकार 0 के साथ realloced नहीं)। इसे मुक्त करना ठीक होना चाहिए क्योंकि insert_node में मैं जांच करता हूं कि कतार को मॉलोकड करने की आवश्यकता है या नहीं। लेकिन यह अभी भी वही त्रुटियां देता है। साथ ही, मुझे अभी भी नहीं पता कि पूरे प्रोग्राम विंडोज या सिर्फ लिनक्स में सही तरीके से क्यों काम करते हैं, क्या आपको कोई विचार है कि ऐसा क्यों है? – HaS

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

  • कोई संबंधित समस्या नहीं^_^