realloc () memoria ING per un buffer utilizzato in recv ()
Domanda
Ho bisogno di recv i dati () da una presa di corrente e memorizzare in un buffer, ma ho bisogno di fare in modo ottenere tutti i dati in modo ho cose in un ciclo. Quindi, per fa in modo non corro fuori dalla stanza nel mio tampone, sto cercando di utilizzare realloc per ridimensionare la memoria allocata per il buffer. Finora ho:
// receive response
int i = 0;
int amntRecvd = 0;
char *pageContentBuffer = (char*) malloc(4096 * sizeof(char));
while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
i += amntRecvd;
realloc(pageContentBuffer, 4096 + sizeof(pageContentBuffer));
}
Tuttavia, questo non sembra funzionare correttamente in quanto Valgrind si lamenta "valgrind: il 'impossibile' accaduto:". Qualche consiglio su come questo dovrebbe essere fatto correttamente?
Grazie, Hristo
Aggiornamento ... mi sono reso conto che stavo usando realloc in modo non corretto. Ecco una versione rivista:
int i = 0;
int amntRecvd = 0;
char *pageContentBuffer = (char*) malloc(4096 * sizeof(char));
while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
i += amntRecvd;
char *temp = realloc(pageContentBuffer, 4096 + sizeof(pageContentBuffer));
if (temp != NULL) {
pageContentBuffer = temp;
}
}
Tuttavia, valgrind ancora si lamenta:
==25812== Syscall param socketcall.recvfrom(buf) points to unaddressable byte(s)
==25812== at 0x33B880DAA1: recv (in /lib64/libpthread-2.5.so)
==25812== by 0x401D78: tunnelURL (proxy.c:371)
==25812== by 0x40142A: client_thread (proxy.c:194)
==25812== by 0x33B8806616: start_thread (in /lib64/libpthread-2.5.so)
==25812== by 0x33B7CD3C2C: clone (in /lib64/libc-2.5.so)
==25812== Address 0x5642768 is 0 bytes after a block of size 4,104 alloc'd
==25812== at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==25812== by 0x401D47: tunnelURL (proxy.c:373)
==25812== by 0x40142A: client_thread (proxy.c:194)
==25812== by 0x33B8806616: start_thread (in /lib64/libpthread-2.5.so)
==25812== by 0x33B7CD3C2C: clone (in /lib64/libc-2.5.so)
Soluzione
sizeof
è un valore fase di compilazione, non è tempo di esecuzione.
E 'possibile per realloc
per tornare 0.
Prova questo ...
// receive response
int i = 0;
int amntRecvd = 0;
int currentSize = 4096;
int oldSize = currentSize;
char *pageContentBuffer = (char*) malloc(currentSize);
while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
i += amntRecvd;
oldSize = currentSize;
currentSize += 4096;
char *newBuffer = malloc(currentSize);
memcpy(newBuffer,pageContentBuffer,oldSize);
free(pageContentBuffer);
pageContentBuffer = newBuffer;
}
La cosa migliore è di ridistribuire, copiare e quindi liberare la memoria in modo esplicito -. realloc
è eccentrico
Altri suggerimenti
A parte ciò @whirlwind detto, c'è anche un secondo problema:
sizeof
non restituisce la quantità di memoria allocata in precedenza, è in realtà un costrutto tempo di compilazione che è equivalente a sizeof(char *)
, cioè la dimensione di un puntatore carattere.
Sarà necessario tenere traccia della lunghezza del buffer manualmente in una variabile. Non esiste un modo standard per "chiedere" la quantità di memoria è stata allocata da malloc / realloc.
Forse c'è un problema perché si sta abusando realloc (). Hai bisogno di vedere se restituisce un nuovo puntatore, e in caso affermativo, negozio che puntatore.
// receive response
int i = 0;
int amntRecvd = 0;
char *pageContentBuffer = (char*) malloc(4096 * sizeof(char));
while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
i += amntRecvd;
pageContentBuffer = realloc(pageContentBuffer, 4096 + sizeof(pageContentBuffer));
}
Il problema principale è che si sta reallocing un importo errato di memoria. Volete
realloc(pageContentBuffer, 4096 + i);
sizeof(pageContentBuffer)
è solo sizeof(char *)
, che significa che stai reallocing molto meno di quanto è necessario per la seconda lettura.