RealLoc () память для буфера, используемого в RECV ()

StackOverflow https://stackoverflow.com/questions/2679719

  •  30-09-2019
  •  | 
  •  

Вопрос

Мне нужно recv () данные из розетки и хранить его в буфер, но мне нужно убедиться, что получить все данные, поэтому у меня есть вещи в цикле. Итак, чтобы убедиться, что у меня нет комнаты в моем буфере, я пытаюсь использовать RealLoc, чтобы изменить размер памяти, выделенной на буфер. Пока у меня есть:

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

Однако, похоже, это не работает должным образом, так как Valgrind жалуется «Valgrind:« невозможное »произошло:«. Любой совет относительно того, как это должно быть сделано правильно?

Спасибо, христо

Обновление ... Я понял, что я использовал Realloc неправильно. Вот пересмотренная версия:

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

Тем не менее, Валгринд по-прежнему жалуется:

==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)
Это было полезно?

Решение

Посмотрите на Realloc.

sizeof Это ценность времени компиляции, а не время выполнения.

Это возможно для realloc вернуться 0.

Попробуй это...

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

Ваша лучшая ставка - перераспределить, скопировать, а затем свободный память явно - realloc причудливый.

Другие советы

Помимо того, что сказал @ Whirlwind, есть также второй вопрос:

sizeof не возвращает объем ранее распределенной памяти, это на самом деле конструкция времени компиляции, которая эквивалентна sizeof(char *), то есть размер указателя символов.

Вам нужно будет отслеживать длину вашего буфера вручную в переменной. Нет стандартного способа «спросить», сколько памяти было выделено Malloc / Realloc.

Возможно, есть проблема, потому что вы не злоупотребляете RealLoc (). Вам нужно посмотреть, возвращает ли он новый указатель, и, если это так, храните этот указатель.

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

Ваша главная проблема заключается в том, что вы перенимаете неправильное количество памяти. Ты хочешь

realloc(pageContentBuffer, 4096 + i);

sizeof(pageContentBuffer) просто sizeof(char *), что означает, что вы перенаправляете гораздо меньше, чем вам нужно для второго чтения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top