Domanda

Sto usando una funzione che ho trovato qui per salvare una pagina web alla memoria con l'arricciatura:

struct WebpageData {
    char *pageData;
    size_t size;
};

size_t storePage(void *input, size_t size, size_t nmemb, void *output) {
    size_t realsize = size * nmemb;

    struct WebpageData *page = (struct WebpageData *)output;

    page->pageData = (char *)realloc(page->pageData, page->size + realsize + 1);
    if(page->pageData) {
        memcpy(&(page->pageData[page->size]), input, realsize);
        page->size += realsize;
        page->pageData[page->size] = 0;
    }

    return realsize;
}

e trovare la linea:

page->pageData = (char *)realloc(page->pageData, page->size + realsize + 1);

sta causando una perdita di memoria di alcune centinaia di byte per chiamata. L'unico vero cambiamento che ho fatto dalla fonte originale sta lanciando la linea in questione a un (char *), che il mio compilatore (gcc, g ++ in particolare se si tratta di C / C ++ problema, ma gcc anche non compilare con il non convertito dichiarazione) insistette, ma suppongo questa è la fonte della fuga di notizie. Qualcuno può elucidate?

Grazie

È stato utile?

Soluzione

Il codice che hai postato (per quanto posso dire) è corretta. Se si tratta di perdite, io sospetta che si sono dimenticando di free() il blocco di memoria ad un certo punto. realloc può creare un intero nuovo blocco di memoria se non può semplicemente ampliare quella esistente, e questo è di interesse per voi. È anche naturalmente permesso di allocare un blocco più grande del necessario, che potrebbe causare le perdite fantasma.

Ora, dal momento che si sta utilizzando C ++, devo chiedere: perché non stai usando std::vector invece?

struct WebpageData {
    std::vector<char> pageData;
    size_t size;
};

size_t storePage(void *input, size_t size, size_t nmemb, void *output) {
    size_t realsize = size * nmemb;
    WebpageData *page = reinterpret_cast<WebpageData *>(output);

    page->pageData.resize(page->size + realsize + 1);
    memcpy(&(page->pageData[page->size]), input, realsize);
    page->size += realsize;
    page->pageData[page->size] = 0;

    return realsize;
}

Altri suggerimenti

Se in via di sviluppo su * nix in generale vorrei provare a eseguire il programma con valgrind ( http://valgrind.org/) per la perdita di memoria problemi realted (in questo caso penso che tu sai dove viene assegnato alla memoria, ma dove è fermo liberato?). In questo caso vorrei suggerire di non utilizzare malloc, realloc e altri simili gestione della memoria c in un programma C ++ se non assolutamente necessario e inevitabile. Essi dovrebbero essere evitati in favore di usare il C ++ strumenti di gestione della memoria, in questo caso credo che la memoria non viene liberata correttamente. Utilizzando C ++ Vettori sarebbe probabilmente rendere la vita molto più facile qui come non avrebbe bisogno di preoccuparsi per il ridimensionamento della matrice e tenere traccia di tutti i cambiamenti nella allocazione di memoria.

Il cast non dovrebbe fare alcuna diference a realloc. Sei sicuro di avere una perdita di memoria? Il codice è aggiungendo i dati, quindi se gli chiedi di storePage tre volte con 1kB dei dati di volta in volta, si memorizzerà 3kB. È questo che si intende quando si copiato e incollato il codice? E, naturalmente, quando hai finito con esso è necessario liberare () il posto di blocco.

Altri pensieri:

  • era il ricordo che si sta reallocing originariamente malloc'd o realloc'd?

  • Si noti che se non si riesce a realloc i dati, si perde tutto. Se si realloc in un puntatore temporaneo e quindi solo sovrascrittura page-> pageData se è valido, questo non accade, e sarete in grado di rilevare l'errore al chiamante (Anche se questo è molto improbabile che si verifichi nella pratica, e probabilmente hanno problemi molto più grandi se lo fa!)

  • Stai reallocing il blocco ogni volta che si riceve nuovi dati. Probabilmente sarà più efficiente di allocare un blocco più grande di quanto richiesto, recuperare i dati in esso, e poi realloc in un blocco di exact-fit solo dopo che tutti i dati sono receieved, in modo da evitare più volte reallocing il blocco.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top