Ошибка сегмента в realloc () в цикле - PullRequest
0 голосов
/ 21 марта 2012

Я пытаюсь перераспределить больше 256 байтов для буферизации при каждом вызове цикла.В этом буфере я буду хранить буфер, полученный из read().

Вот мой код:

#define MAX_BUFFER_SIZE 256
//....
int sockfd = socket( ... );

char *buffer;
buffer = malloc( MAX_BUFFER_SIZE );
assert(NULL != buffer);
char *tbuf =  malloc(MAX_BUFFER_SIZE);
char *p = buffer;
int size = MAX_BUFFER_SIZE;

while( read(sockfd, tbuf, MAX_BUFFER_SIZE) > 0 ) {
    while(*tbuf) *p++ = *tbuf++;
    size = size + MAX_BUFFER_SIZE; // it is the right size for it?
    buffer  = realloc(buffer, size);
    assert(NULL != buffer); 
}


printf("%s", buffer);
free(tbuf); 
free(p);
free(buffer);
close(sockfd);

Но приведенный выше код возвращает ошибку сегмента.Где я не прав?

Ответы [ 3 ]

2 голосов
/ 21 марта 2012

Это проблемы, которые мне очевидны:

  • Ваш realloc может изменить местоположение, на которое указывает buffer. Но вы не можете изменить p соответственно, и он остается указанным в предыдущем буфере. Это явно ошибка.
  • Я вижу потенциал для другой ошибки в том, что цикл while не должен заканчиваться и может выполняться за пределами буфера. Это наиболее вероятная причина ошибки сегментации.
  • То, как вы используете realloc, неверно. Если вызов realloc не удался, вы больше не можете free исходный буфер. Вы должны присвоить возвращаемое значение realloc временной переменной и проверить наличие ошибок перед тем, как перезаписать переменную buffer.
  • Не следует звонить free по указателю p. Так как он предназначен для указания на блок, принадлежащий buffer, вы звоните free только на buffer.
2 голосов
/ 21 марта 2012

Когда вы используете realloc на buffer, возможно, что адрес buffer будет изменен в результате изменения размера.Как только это произойдет, p больше не будет содержать правильный адрес.

Также к концу вы освобождаете p и buffer, пока они указывают на одно и то же место.Вы должны освободить только одного из них.

2 голосов
/ 21 марта 2012

Значение read не добавляет 0-терминатор .Таким образом, ваш внутренний while, несомненно, выходит за пределы выделенной памяти:

while(*tbuf) *p++ = *tbuf++;

Другая проблема заключается в том, что вы освобождаете то, что не получили через malloc.К тому времени, когда вы звоните бесплатно, вы увеличиваете как p, так и tbuff, которые вы пытаетесь освободить.

Весь процесс выделения buffer выглядит бесполезным, поскольку вы его фактически нигде не используете.

...