Объяснение переполнения стека при использовании чтения небольшого файла и сомнительный обходной путь

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

  •  06-07-2019
  •  | 
  •  

Вопрос

Надеюсь, вопрос объяснил мою проблему.Я также был бы признателен, если бы был объяснен обходной путь, который «работает».

Традиционный способ чтения файла (который я знаю)

int fd;
char buffer[MAX];
while(read(fd,buffer,MAX)>0)
{
         buffer[MAX]='\0';
         write(sockfd,buffer,MAX);
         memset(buffer,NULL,MAX);
}

вызывало переполнение.Обходной путь, который каким-то образом неожиданно сработал, был

   while((read(fd,buffer,MAX)!=0)||(read(fd,buffer,MAX)!= -1))
   {
         buffer[MAX]='\0';
         write(sockfd,buffer,MAX);
         memset(buffer,NULL,MAX);

   }

^^ Этот код распечатывает весь файл, без пропусков, насколько это заметно.

Вещи как

do
{
     int temp;
     temp=read(fd,buffer,MAX);
     if((temp == 0) || (temp == -1))
     {
              break;
     }
     buffer[MAX]='\0';
     write(sockfd,buffer,MAX);
     memset(buffer,NULL,MAX);
 }while(1);

также вызвало переполнение стека.Я упускаю здесь что-то действительно важное?

Спасибо

Это было полезно?

Решение

Почему вы говорите, что это вызывает переполнение?

Обратите внимание, что read() не буду писать \0 в конце char массив, поэтому, если вы сделаете что-то вроде printf("%s", buffer) скорее всего, это потерпит неудачу, потому что printf будет ожидать строку, завершающуюся NUL.Возможно, вы захотите прочитать MAX-1 и установить buffer[number_of_read_characters] = '\0' где число_прочитанных_символов это что угодно read() возвращается, если положительный.

Также обратите внимание, что когда вы объявляете char buffer[MAX], поскольку в C индексация начинается с нуля, наивысший buffer индекс MAX-1, поэтому, когда вы настраиваете buffer[MAX]='\0' вы уже вышли за пределы своего массива.

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

Одна проблема:

buffer[MAX]='\0';

шагов в стеке, так как наивысший действительный индекс для массива размера MAX равен MAX-1 (из-за индексов, отсчитываемых от 0).

Возвращаемое значение -1 из read указывает на ошибку, поэтому правильно проверять read() > 0.Более того, обычное возвращаемое значение чтения — это количество прочитанных байтов, а чтение не гарантирует никакого 0-завершения.вам нужно сделать что-то в духе

while (bytesRead=read() > 0) {
    write(buffer, bytesRead);
...

Глядя на код, я бы предположил, что это потому, что логика другая.

В примере, который работает, read(fd,buffer,MAX) метод выполняется дважды.

Подумайте об этом так:

while (dosomething() != 0 || dosomething() != -1)
{
    // some work
}

Этот цикл будет бесконечным, если метод dosomething() является идемпотентным, однако, если первый раз, когда вы запускаете его в операторе while, отличается от второго, он прервется.

Это объясняет, чем отличается путь выполнения, но я не могу понять, почему первый вариант переполняется...Я подумаю об этом и обновлю.(или нет - кажется, на него ответили!)

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

int fd, readCharacter;
char buffer[MAX];
while( readCharacter = read(fd, buffer, MAX**-1**) > 0 )
{
    buffer[readCharacter] = '\0';
    // ...
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top