2010-04-21 10 views
1

J'ai besoin de recv() les données d'une socket et de les stocker dans un tampon, mais je dois m'assurer d'avoir toutes les données pour avoir des choses dans un boucle. Donc, pour m'assurer que je ne manque pas de place dans mon buffer, j'essaye d'utiliser realloc pour redimensionner la mémoire allouée au buffer. Jusqu'à présent, j'ai:realloc() ing mémoire pour un tampon utilisé dans recv()

// 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)); 
} 

Cependant, cela ne semble pas fonctionner correctement car Valgrind se plaint « valgrind: le « impossible » est arrivé: ». Des conseils sur la façon dont cela devrait être fait correctement?

Merci, Hristo

mise à jour ... J'ai réalisé que j'utilisais realloc mal. Voici une version révisée:

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; 
    } 
} 

Cependant, valgrind est encore plaint:

==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) 

Répondre

0

Look up realloc.

sizeof est une valeur de temps de compilation, pas d'exécution.

Il est possible de retourner realloc 0.

Essayez cette ...

// 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; 
} 

Votre meilleur pari est de réallouer, copier et libérer la mémoire explicite - realloc est décalé.

+0

pouvez-vous me donner un exemple précis de « Votre meilleur pari est de réallouer, copier puis supprimer la mémoire explicite » – Hristo

+0

@Hristo int oldSize = la taille actuelle; currentSize + = 4096; char * newBuffer = malloc (currentSize); memcpy (newBuffer, pageContentBuffer, oldSize); gratuit (pageContentBuffer); pageContentBuffer = newBuffer; Je ne l'ai pas vérifié, mais c'est l'essentiel –

+0

@Hristo - J'ai mis à jour le code –

2

Peut-être il y a un problème parce que vous vous détournez realloc(). Vous devez voir si elle renvoie un nouveau pointeur, et si c'est le cas, stockez ce pointeur.

// 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)); 
} 
3

En dehors de ce @whirlwind dit, il y a aussi une deuxième question:

sizeof ne retourne pas la quantité de mémoire précédemment alloué, il est en fait une construction de compilation qui équivaut à sizeof(char *), à savoir la taille d'un pointeur de caractères.

Vous aurez besoin de garder une trace de la longueur de votre tampon manuellement dans une variable. Il n'y a pas de façon standard de "demander" combien de mémoire a été allouée par malloc/realloc.

+0

Eh oui, sizeof (pageContentBuffer) est le même que sizeof (char *) – WhirlWind

1

Votre principal problème est que vous réaffectez la mauvaise quantité de mémoire. Vous voulez

realloc(pageContentBuffer, 4096 + i); 

sizeof(pageContentBuffer) est juste sizeof(char *), ce qui signifie que vous reallocing beaucoup moins que vous avez besoin pour la deuxième lecture.