संपादित करें: सभी वालग्रिंड त्रुटियां जहां i प्रारंभ करके हल की गई हैं।


मैं तार के साथ काम कर रहा हूँ; एक फ़ाइल से स्ट्रिंग्स पढ़ना, उन्हें strsep() का उपयोग करके अलग करना, उन्हें atol() का उपयोग करके int में परिवर्तित करना। मेरा कोड जीसीसी पर संकलित है और त्रुटियों के बिना चलता है, लेकिन जब वालग्रिंड के साथ जांच की जाती है तो मुझे शीर्षक में उल्लिखित त्रुटि मिलती है।

मैं एक टेक्स्ट फ़ाइल से int मानों के साथ एक द्वि-आयामी सरणी grid[20][20] को पॉप्युलेट करने का प्रयास कर रहा हूं। टेक्स्ट फ़ाइल में रिक्त स्थान द्वारा अलग की गई संख्याओं की पंक्तियाँ होती हैं, जैसे 20 81 65 07 54 72 13 28 66 95 00 20 00 84 06 30 85 43 15 73\n

मेरा कोड, (सभी फाइल आईओ को छोड़कर) नीचे जैसा है। (ध्यान दें कि मैं फ़ाइल को सही ढंग से संभालता हूं: fopen के परिणाम की जांच करना, fclose के साथ बंद करना)।

अपडेट किया गया कोड

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STR_LEN     20
#define NUM_LINES   20
#define MAX_SIZE    100

int main(void){
    char input_str[MAX_SIZE];   //string to hold lines read from file
    char * str_array[STR_LEN];  //array of strings to split the lines into
    int grid[20][20];
    char * token, *str, *tofree;
    int line;
    for (line = 0; line < NUM_LINES; ++line){   //for every line in the file 

        if (fgets(input_str, MAX_SIZE, fp)!=NULL){  //read the file's line into input_str
            tofree = str = strdup(input_str);   //set str to copy of input_string, and tofree to point to beginning of str's memory, to free later

            int i = 0;
            while ((token = strsep(&str, " "))){    //split str on " ", keeping everything in between in token
                str_array[i] = token;   //add token to str_array
                ++i;
            }
            for (i = 0; i < STR_LEN; ++i){
                grid[line][i] = atol(str_array[i]); //convert strings to int and store in num_array     
                printf("grid[%d][%d]: %d\n", line, i, grid[line][i]);

            }
            free(tofree);   //free str by freeing tofree, as tofree points to str's memory
        }
    }
    printf("%d", grid[0][0]);
    return 0;
}

मैं इस कोड को gcc -Wall -g -c myfile.c के साथ संकलित करता हूं। यह बिना किसी त्रुटि के संकलित और ठीक चलता है। मानों को grid में पास करने के ठीक बाद printf() का उपयोग करके मानों की जांच करना सभी सही मान दिखाता है। हालांकि, कोड में अंतिम printf() से पता चलता है कि grid[0][0] में जंक है, भले ही वह पहले सही था। वास्तव में, grid[0] में सभी तत्व दूषित हो गए हैं।

valgrind --leak-check=full --track-origins=yes --dsymutil=yes --show-leak-kinds=all ./productGrid.elf के साथ चलने वाला वालग्रिंड मुझे देता है

$ valgrind --leak-check=full --track-origins=yes --dsymutil=yes --show-leak-kinds=all ./productGrid.elf

==2252== Command: ./productGrid.elf
==2252== 
==2252== Use of uninitialised value of size 4
==2252==    at 0x106EC: main (in /home/jesse/C/Proj. Euler/productGrid.elf)
==2252==  Uninitialised value was created by a stack allocation
==2252==    at 0x10656: main (in /home/jesse/C/Proj. Euler/productGrid.elf)
==2252== 
==2252== Invalid write of size 4
==2252==    at 0x106EC: main (in /home/jesse/C/Proj. Euler/productGrid.elf)
==2252==  Address 0x7e2b6c38 is not stack'd, malloc'd or (recently) free'd
==2252== 
==2252== 
==2252== Process terminating with default action of signal 11 (SIGSEGV)
==2252==  Access not within mapped region at address 0x7E2B6C38
==2252==    at 0x106EC: main (in /home/jesse/C/Proj. Euler/productGrid.elf)
==2252==  If you believe this happened as a result of a stack
==2252==  overflow in your program's main thread (unlikely but
==2252==  possible), you can try to increase the size of the
==2252==  main thread stack using the --main-stacksize= flag.
==2252==  The main thread stack size used in this run was 8388608.
==2252== 
==2252== HEAP SUMMARY:
==2252==     in use at exit: 413 bytes in 2 blocks
==2252==   total heap usage: 3 allocs, 1 frees, 4,509 bytes allocated
==2252== 
==2252== 61 bytes in 1 blocks are still reachable in loss record 1 of 2
==2252==    at 0x483E380: malloc (vg_replace_malloc.c:299)
==2252==    by 0x48E188B: strdup (strdup.c:42)
==2252==    by 0x106C9: main (in /home/jesse/C/Proj. Euler/productGrid.elf)
==2252== 
==2252== 352 bytes in 1 blocks are still reachable in loss record 2 of 2
==2252==    at 0x483E380: malloc (vg_replace_malloc.c:299)
==2252==    by 0x48D11F3: __fopen_internal (iofopen.c:69)
==2252==    by 0x10681: main (in /home/jesse/C/Proj. Euler/productGrid.elf)
==2252== 
==2252== LEAK SUMMARY:
==2252==    definitely lost: 0 bytes in 0 blocks
==2252==    indirectly lost: 0 bytes in 0 blocks
==2252==      possibly lost: 0 bytes in 0 blocks
==2252==    still reachable: 413 bytes in 2 blocks
==2252==         suppressed: 0 bytes in 0 blocks
==2252== 
==2252== For counts of detected and suppressed errors, rerun with: -v
==2252== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 6 from 3)
Segmentation fault

मैं क्या गलत कर रहा हूँ पर कोई विचार?

0
hat 30 जून 2018, 13:22

3 जवाब

सबसे बढ़िया उत्तर

i का प्रयोग यहां आरंभिक रूप से नहीं किया गया है:

  str_array[i] = token; 
  ++i;

ध्यान दें:

यदि आप प्रतीकों के साथ संकलित करते हैं (विकल्प -g जीसीसी के लिए) तो वालग्रिंड स्रोत लाइनों के संदर्भ में इसके लॉगिंग को एनोटेट करता है।

2
alk 30 जून 2018, 13:28

मैं टिप्पणी नहीं कर सकता, इसलिए मैं एक नया उत्तर पोस्ट करता हूं। जैसा कि @alk ने कहा, i यह अप्रारंभीकृत है और यदि आप इसे केवल परिभाषा पर प्रारंभ करते हैं, तो समय काम नहीं करेगा। एक for(;;) का प्रयोग करें, क्योंकि आपको असाइनमेंट की आवश्यकता है।

यदि आपको अभी भी समस्या हो रही है तो अपना कोड अपडेट करें।

1
Mance Rayder 30 जून 2018, 13:35

आपको शुरुआत में i को इनिशियलाइज़ करना चाहिए।

कोड के इस टुकड़े के बारे में भी:

while ((token = strsep(&str, " "))){
    str_array[i] = token;   //add token to str_array
    ++i;
 }

for (i = 0; i < STR_LEN; ++i){
     grid[line][i] = atol(str_array[i]);
     printf("grid[%d][%d]: %d\n", line, i, grid[line][i]);
}

यदि आप इसे नीचे शून्य करने जा रहे हैं तो आप i की गिनती क्यों कर रहे हैं? हो सकता है कि आपको तब तक एक अलग काउंटर और लूप का उपयोग करना चाहिए, न कि STR_LEN।

उम्मीद है ये मदद करेगा।

1
Alex G 30 जून 2018, 13:48