Как вырастить динамический c буфер с read ()? - PullRequest
0 голосов
/ 23 февраля 2020

Так что у меня возникли некоторые проблемы с тем, чтобы обернуть голову вокруг наращивания буфера, из того, что я вижу, я определенно читаю все байты из файлового дескриптора, но, похоже, я не храню их в буфер правильно. Может ли кто-нибудь помочь направить меня в правильном направлении?

char *read_all(int fd, int *nread){ //nread tracks total bytes read
  int max_size = 1;
  *nread = 0;
  char *buf = malloc(max_size*sizeof(char));
  int bytes_read = read(fd, buf, max_size*sizeof(char));
  while(bytes_read > 0){ 
    *nread+=bytes_read;
    if(*nread >= max_size*sizeof(char)){
      max_size*=2;
      buf = realloc(buf, max_size*sizeof(char));
    }
    bytes_read = read(fd, buf, max_size*sizeof(char));
  }
  return buf;
}
==== EXPECT ====                                                       ==== ACTUAL ====                                                    
{                                                                      {
    // Tests the read_all() function to ensure that                        // Tests the read_all() function to ensure that
    // it properly accumulates all data from an                            // it properly accumulates all data from an
    // arbitrary input FD including allocating memory                      // arbitrary input FD including allocating memory
    // for the data.                                                       // for the data. 
    int fd = open("test-data/quote.txt", O_RDONLY);                        int fd = open("test-data/quote.txt", O_RDONLY);
    int bytes_read = -1;                                                   int bytes_read = -1;
    char *actual_read = read_all(fd, &bytes_read);                         char *actual_read = read_all(fd, &bytes_read);
    int result = close(fd);                                                int result = close(fd);
    printf("result: %d\n", result);                                        printf("result: %d\n", result);
    printf("bytes_read: %d\n", bytes_read);                                printf("bytes_read: %d\n", bytes_read);
    actual_read[bytes_read] = '\0';                                        actual_read[bytes_read] = '\0';
    printf("actual_read:\n" );                                             printf("actual_read:\n" );
    printf("--------------------\n" );                                     printf("--------------------\n" );
    printf("%s",actual_read);                                              printf("%s",actual_read);
    printf("--------------------\n" );                                     printf("--------------------\n" );
    free(actual_read);                                                     free(actual_read);
}                                                                      }
result: 0                                                              result: 0
bytes_read: 125                                                        bytes_read: 125
actual_read:                                                           actual_read:
--------------------                                                   --------------------
Object-oriented programming is an exceptionally bad idea which could | could
only have originated in California.                                    only have originated in California.

-- Edsger Dijkstra                                                     -- Edsger Dijkstra
--------------------                                                   --------------------
ALERTS:                                                                ALERTS:
                                                                     (

Ответы [ 2 ]

0 голосов
/ 23 февраля 2020

Спасибо, ребята, мне удалось решить эту проблему, ключ передавал & buf [* nread] в read ().

char *read_all(int fd, int *nread){
  int bytes_read = 0, size_mult = 1;
  *nread = 0;
  char * buf = malloc(1024);
  bytes_read = read(fd, &buf[*nread], 256);
  while(bytes_read > 0){
    *nread += bytes_read;
    if(*nread > size_mult*512){
      size_mult*=2;
      buf = realloc(buf, size_mult*1024);
    }
    bytes_read = read(fd, &buf[*nread], 256);
  }
  return buf;
}
0 голосов
/ 23 февраля 2020

Немного странно ... Я изменил read_all (), чтобы он работал больше, чем ожидалось: ( полный здесь )

char *read_all2(int fd, int *nread){ //nread tracks total bytes read
  int max_size = 1;
  *nread = 0;
  char *buf = malloc(max_size*sizeof(char));
  char *ptr = buf;
  int bytes_read = 0;
  //while(bytes_read > 0)
  do
  {
    fprintf(stderr, "bytes_read=%d\n", bytes_read);
    *nread += bytes_read;
    ptr += bytes_read;
    if(*nread >= max_size*1){
      max_size *= 2;
      fprintf(stderr, "realloc(buf=%08x, max_size=%d)\n", buf, max_size);
      buf = realloc(buf, max_size*1);
    }
  } while((bytes_read = read(fd, ptr, max_size*1)) > 0);
  return buf;
}

, но когда он realloc(buf, 16);, он падает.

$ gcc -o readynbuf2 readynbuf2.c ; ./readynbuf2
bytes_read=0
bytes_read=1
realloc(buf=016ba008, max_size=2)
bytes_read=2
realloc(buf=016ba008, max_size=4)
bytes_read=4
realloc(buf=016ba008, max_size=8)
bytes_read=8
realloc(buf=016ba008, max_size=16)
*** Error in `./readynbuf2': realloc(): invalid next size: 0x016ba008 ***

У меня нет идей, почему это случилось.

...