realloc() память для буфера, используемого в 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)
4 ответа
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 *)
Это означает, что вы перераспределяете гораздо меньше, чем нужно для второго чтения.