Прерывания программы после прочтения нескольких сотен строк - PullRequest
0 голосов
/ 15 ноября 2018

Я сделал функцию сканирования, которая по сути просто сканирует строки файла в один char *, называемый buffer. Однако после прочтения пары сотен программа просто перестает работать. У меня просто программа перестала работать всплывающее окно. Предполагая, что я сделал что-то не так с распределением памяти, но я не уверен, что.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *scan_file(FILE *fp);

#define MAX_LINE                200


int main(void) {
    FILE *fp = fopen("test.txt", "r");
    char *contents = scan_file(fp);
    printf("%s\n", contents);
    return 0;
}
// Scan in file into a buffer. Returns a malloc-ed string
char *scan_file(FILE *fp) {

    int buf_len = 1;
    int contents_len = buf_len;

    char *buffer = malloc(sizeof(char) * (MAX_LINE + 1));
    char *contents = malloc(sizeof(char) * (buf_len + 1));
    strcpy(contents, "\0");

    while (fgets(buffer, MAX_LINE, fp) != NULL) {
        buf_len = strlen(buffer);
        contents_len += buf_len;
        realloc(contents ,contents_len);
        strcat(contents, buffer);
        strcpy(buffer, "\0");
    }

    free(buffer);
    return contents;
}

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018
  • использование realloc() s возвращаемое значение
  • realloc(NULL, size) работает так же, как malloc(size);нет необходимости предварительно выделять
  • , избегайте чрезмерного копирования и strlen()
  • , просто поместите данные туда, куда вы хотите, при первом (и единственном) прикосновении к ним.

#include <stdio.h>
#include <stdlib.h>

char *scanfile (FILE *fp)
{
size_t size, used;
char *buff = NULL;
int ch;

for (size=used=0;;      ) {
        ch = getc(fp);
        if (ch == EOF) break;
        if (used+1 >= size) {
                size_t newsize = used? 2*used: 1024 ;
                char *tmp = realloc(buff, newsize);
                if (!tmp) FAIL();
                else {buff = tmp; size = newsize; }
                }
        buff[used++] = ch;
        }

        /* Nothing read: return NULL */
if (!used) return NULL;
buff[used++] = 0;

/* maybe realloc (shrink) buff here */
return buff;
}
0 голосов
/ 15 ноября 2018

Код не может использовать форму возвращаемого значения realloc()

Размеры распределения отключены на 1.

Повтор strcat() создает медленное (n * n) решение.

Попробуйте использовать size_t для размеров массива против int.

Вместо того, чтобы вызывать переменную ...len, рассмотрите ...size, чтобы подтвердить наличие последнего нулевого символа в строке .

char *scan_file(FILE *fp) {
    // int buf_len = 1;
    size_t buf_size = 1;

    // int contents_len = buf_len;
    size_t contents_size = buf_size;

    // char *buffer = malloc(sizeof(char) * (MAX_LINE + 1));
    // fgets(..., MAX_LINE, ...) will only read up to MAX_LINE - 1 characters.
    char *buffer = malloc(MAX_LINE);

    char *contents = malloc(buf_size + 1u);
    if (buffer == NULL || contents == NULL) {
      fprintf(stderr, "Out of memory\n");
      return EXIT_FAILURE;
    }

    // strcpy(contents, "\0");
    contents[0] = '\0';

    while (fgets(buffer, MAX_LINE, fp) != NULL) {
        // buf_len = strlen(buffer);
        buf_size = strlen(buffer) + 1u;

        // contents_len += buf_len;

        // realloc(contents ,contents_len);
        void *p = realloc(contents ,contents_size + buf_size);
        if (p == NULL) {
          fprintf(stderr, "Out of memory\n");
          return EXIT_FAILURE;
        }
        contents = p;

        // strcat(contents, buffer);
        strcpy(contents + contents_size, buffer);

        // now add
        contents_size += buf_size;

        // Code here not truly needed, yet helps in debugging.
        // strcpy(buffer, "\0");
        buffer[0] = '\0';
    }

    free(buffer);
    return contents;
}
...