मैं पुराने सी कोड में मेमोरी डीलोकेशन जोड़ने की कोशिश कर रहा हूं। मेरे पास कस्टम ऑब्जेक्ट्स (हैशरेक) की हैश टेबल है। वर्तमान कोड के विश्लेषण और अन्य SO प्रश्नों को पढ़ने के बाद, मुझे पता है कि मुझे डीललोकेशन के तीन स्तर प्रदान करने की आवश्यकता है। मुट्ठी - शब्द सदस्य, अगला HASREC*, और फिर HASREC**।

free_table() फ़ंक्शन का मेरा संस्करण उल्लिखित वस्तुओं को मुक्त करता है। दुर्भाग्य से, वालग्रिंड अभी भी शिकायत करता है कि कुछ बाइट खो गए हैं।

मैं पूर्ण कोड प्रदान करने में सक्षम नहीं हूं, यह बहुत लंबा होगा, लेकिन मैं प्रस्तुत कर रहा हूं कि HASHREC **vocab_hash initashtable() और hashinsert() के अंदर कैसे भरा जाता है। क्या आप मुझे सुझाव दे सकते हैं कि मुझे free_table() कैसे ठीक करना चाहिए?

typedef struct hashrec {
    char *word;
    long long count;
    struct hashrec *next;
} HASHREC;

HASHREC ** inithashtable() {
    int i;
    HASHREC **ht;
    ht = (HASHREC **) malloc( sizeof(HASHREC *) * TSIZE );
    for (i = 0; i < TSIZE; i++) ht[i] = (HASHREC *) NULL;
    return ht;
}

void hashinsert(HASHREC **ht, char *w) {
    HASHREC     *htmp, *hprv;
    unsigned int hval = HASHFN(w, TSIZE, SEED);

    for (hprv = NULL, htmp = ht[hval]; htmp != NULL && scmp(htmp->word, w) != 0; hprv = htmp, htmp = htmp->next);
    if (htmp == NULL) {
        htmp = (HASHREC *) malloc( sizeof(HASHREC) );  //<-------- problematic allocation (Valgrind note)
        htmp->word = (char *) malloc( strlen(w) + 1 );
        strcpy(htmp->word, w);
        htmp->next = NULL;
        if ( hprv==NULL ) ht[hval] = htmp;
        else hprv->next = htmp;
    }
    else {/* new records are not moved to front */
        htmp->count++;
        if (hprv != NULL) { /* move to front on access */
            hprv->next = htmp->next;
            htmp->next = ht[hval];
            ht[hval] = htmp;
        }
    }
    return;
}

void free_table(HASHREC **ht) {
    int i;
    HASHREC* current;
    HASHREC* tmp;
    for (i = 0; i < TSIZE; i++){
        current = ht[i];
        while(current != NULL) {
            tmp = current;
            current = current->next;
            free(tmp->word);
        }
        free(ht[i]);
    }
    free(ht);
}

int main(int argc, char **argv) {
    HASHREC **vocab_hash = inithashtable();
    // ...
    hashinsert(vocab_hash, w);
    //....
    free_table(vocab_hash);
    return 0;
}
2
flamingo 19 जिंदा 2020, 02:09

1 उत्तर

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

मुझे लगता है कि समस्या यहाँ है:

current = ht[i];
while(current != NULL) {
    tmp = current;
    current = current->next;
    free(tmp->word);
}
free(ht[i]);

आप word को रिलीज़ करते हैं लेकिन आप tmp को रिलीज़ नहीं करते हैं। आपके द्वारा लिंक की गई सूची में पहला आइटम जारी करने के बाद, लेकिन अन्य नहीं जो रिसाव का कारण बनता है।

वहां मुफ़्त tmp और ht[i] को मुफ़्त न दें, क्योंकि यह पहले ही यहां मुक्त हो चुका है।

current = ht[i];
while(current != NULL) {
    tmp = current;
    current = current->next;
    free(tmp->word);
    free(tmp);
}
4
Sami Kuhmonen 18 जिंदा 2020, 23:14