2013-10-16 5 views
5

में अनपेक्षित परिवर्तन मैंने char को Token में परिवर्तित करने के लिए एक सरल सी प्रोग्राम लिखा है। चीजें ठीक काम करती हैं लेकिन मुझे समझ में नहीं आता कि size परिवर्तनीय मान क्यों बदल रहा है।सी परिवर्तनीय

typedef struct _token { 
    int val; 
} Token; 

void parse(char* code, int size, Token** tokens) { 
    int i = 0; 
    for (; i < size; i++) { 
     tokens[i] = malloc(sizeof(Token)); 
     tokens[i]->val = code[i]; 
    } 
} 

int execute(char *path) { 
    char* code; 
    if (read_file(path, &code) != 0) { 
     return -1; 
    } 
    int size = strlen(code) - 1; 
    printf("BEFORE PARSE: %d\n", size); // 1st printf 
    Token *tokens; 
    parse(code, size, &tokens);   
    printf("AFTER PARSE: %d\n", size);  // 2nd printf 
    return 0; 
} 

अगर code"abcde" होता है, उत्पादन होता है: विभिन्न रन पर

BEFORE PARSE: 5 
AFTER PARSE: 142786584 

दूसरा printf प्रदर्शित करता है विभिन्न मूल्यों।

कृपया मदद करें!

पीएस: मैं एक सी नोब हूँ!

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

int read_file(char* path, char** code) { 
    FILE* fp = fopen (path , "rb"); 
    if(!fp) { 
     return -1; 
    } 

    fseek(fp , 0L , SEEK_END); 
    long lSize = ftell(fp); 
    rewind(fp); 

    /* allocate memory for entire content */ 
    *code = calloc(1, lSize+1); 
    if(!*code) { 
     fclose(fp); 
     return -1; 
    } 

    /* copy the file into the buffer */ 
    if(1 != fread(*code , lSize, 1 , fp)) { 
     fclose(fp); 
     return -1; 
    } 

    fclose(fp); 
    return 0; 
} 
+2

आप malloc टोकन की जरूरत है इससे पहले कि आप पार्स कहते हैं। –

उत्तर

3

आप बफर अतिप्रवाह का एक विशिष्ट मामला है।

char* code; 

एक बफर अपनी फ़ाइल डेटा रखने के लिए चरित्र के लिए एक सूचक (आमतौर पर 8 बाइट्स), नहीं का आवंटन।

साथ

Token *tokens; 

जब आप parse में tokens को लिखने आप अपने ढेर के हिस्से के ऊपर लिख

एक ही है और इसके साथ size

उनके लिए पर्याप्त स्मृति आवंटित करें!

read_file(path, code); 
parse(code, size, tokens); 

यहाँ कोड में सुधार किया जाए:

char * code = malloc(0x1000); 
Token *tokens = malloc(0x100 * sizeof(Token *)); 

और सूचक पास, नहीं यह पता है

typedef struct _token { 
    int val; 
} Token; 

void parse(char* code, int size, Token* tokens) { 
    int i = 0; 
    for (; i < size; i++) { 
      // you already have memory now 
     tokens[i]->val = code[i]; 
    } 
} 

int execute(char *path) { 
    char* code = malloc(0x1000); 
    if (read_file(path, code) != 0) { 
     return -1; 
    } 
    int size = strlen(code) - 1; 
    printf("BEFORE PARSE: %d\n", size); // 1st printf 
    Token *tokens = calloc(sizeof(Token), 0x100); 
    parse(code, size, tokens);   
    printf("AFTER PARSE: %d\n", size);  // 2nd printf 
    return 0; 
} 
+0

आप टोकन के बारे में सही हैं, लेकिन ऐसा लगता है कि कोड को शायद read_file() में आवंटित बफर को इंगित करने के लिए बदला जा रहा है - जो निष्पादित() –

+0

@ChrisStratton मई में कार्यान्वित कार्यान्वयन की शैली के अनुरूप होगा। उन्होंने read_file के लिए कोड की आपूर्ति नहीं की, इसलिए मैं निश्चित रूप से नहीं बता सकता। हालांकि यह बल्कि असामान्य होगा। –

+0

यह ऑपरेटर के उपयोग के लिए तार्किक स्पष्टीकरण है, और स्टाइलिस्टिक रूप से कोड के साथ संगत है जो आपूर्ति की गई है। इसके अलावा, भले ही आप किसी भी तरह सही थे, यह समस्या का कारण नहीं हो सकता है, जो बाद में ही होता है। –

5

यह इसलिए क्योंकि टोकन प्रारंभ कभी नहीं किया गया है।

Tokens **tokens = malloc(sizeof(Tokens *) * size); 

स्मृति को मुक्त करने के लिए मत भूलना जब आप इसे के साथ किया जाता है:: यह करने के लिए परिवर्तित

for (; i < size; i++) { 
    free(tokens[i]); 
} 

free(tokens); 
+0

क्या आप वाकई 'फ्री (टोकन [i])' कॉल करना चाहते हैं? आप एक सूचक के बजाय एक संरचना गुजर रहे हैं। इसके अलावा आपको चेतावनी दी जा सकती थी कि आप केवल एक मॉलोक() 'को कॉल कर रहे हैं लेकिन एक लूप में 'फ्री()' को कॉल कर रहे हैं। इस तरह वे कभी मेल नहीं खा सकते हैं। –

+0

इसके अलावा 'आकार (टोकन *)' गलत है जब किसी सरणी को आवंटित किया जाता है जिसका तत्व 'टोकन' प्रकार होता है, न कि 'टोकन *'। –

+1

@ पावेल सिमरडा 'पार्स()' के अंदर 'वह व्यक्तिगत टोकन संरचनाओं को आवंटित कर रहा है:' टोकन [i] = malloc (sizeof (टोकन)); 'तो 'टोकन'' टोकन * 'की एक सरणी है। लेकिन हां, सही होने के लिए, 'टोकन' को 'टोकन **' के रूप में घोषित किया जाना चाहिए और उसे यह भी अपडेट करना होगा कि 'पार्स' इसे कैसे एक्सेस करता है। –

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