Объяснение переполнения стека при использовании чтения маленького файла и сомнительного обходного пути - PullRequest
1 голос
/ 27 октября 2009

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

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

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

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

Спасибо

Ответы [ 4 ]

3 голосов
/ 27 октября 2009

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

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

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

1 голос
/ 27 октября 2009

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

buffer[MAX]='\0';

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

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

while (bytesRead=read() > 0) {
    write(buffer, bytesRead);
...
0 голосов
/ 27 октября 2009

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

int fd, readCharacter;
char buffer[MAX];
while( readCharacter = read(fd, buffer, MAX**-1**) > 0 )
{
    buffer[readCharacter] = '\0';
    // ...
}
0 голосов
/ 27 октября 2009

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

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

Думайте об этом как:

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...