#c #stdio
#c #stdio
Вопрос:
Я хочу обработать содержимое конфигурационного файла. Файл конфигурации может быть любого размера. Я получаю сообщение об ошибке шины после зависания программы, когда я запускаю следующий код:
FILE *fp;
struct stat st;
char *buffer;
fp = fopen(CONFIG_FILE, "r");
if (fp == NULL) {
// error handling and cleanup omitted for brevity
}
fstat(fileno(fp), amp;st);
fread(buffer, sizeof(char), st.st_size, fp);
fprintf(stderr, "%sn", *buffer);
fclose(fp);
Я прочитал, что ошибка шины может быть вызвана переполнением буфера. Я почти уверен, что у меня происходит переполнение буфера с моим char *buffer
. Но тогда, как я могу указать размер буфера во время выполнения?
РЕДАКТИРОВАТЬ — Ошибка шины была вызвана моей ленью жесткого кодирования 1
в вызове fread. Пример кода был обновлен, чтобы исправить это, используя sizeof(char)
вместо этого.
Комментарии:
1.
sizeof(char) == 1
гарантировано.2. @Alok, это то, что я думал, но произошел сбой, когда у меня был 1… ну что ж, жесткое кодирование в любом случае плохое
3. Стандарт C гарантирует, что
sizeof(char)
равно 1. Так что в этом случае с жестким кодированием все в порядке.
Ответ №1:
Использовать malloc(3)
. Поместить:
buffer = malloc(st.st_size);
Перед вашим вызовом в fread()
. Не забудьте освободить buffer
, когда закончите с этим!
Вы, вероятно, также не хотите использовать его *buffer
в своем printf()
вызове. Если вы собираетесь попытаться распечатать весь файл таким образом, вам нужно обязательно выделить дополнительный байт для завершения строки нулем.
Комментарии:
1. @Карл, когда я вводю malloc(st.st_size 1), я явно задаю последнему элементу значение
?
2. @Mad Rapper X — это должно сработать, да. @muntoo, о чем ты спрашиваешь?
Ответ №2:
Вы можете выделить память с помощью malloc
:
buffer = malloc(number_of_bytes_to_allocate);
if(buffer == NULL) {
// error allocating memory
}
free
когда вы закончите с этим!
free(buffer);
Ответ №3:
В C99 и при условии, что ваш конфигурационный файл не должен находиться в диапазоне MiB или большем, вы могли бы использовать VLA:
FILE *fp = fopen(CONFIG_FILE, "r");
if (fp == NULL) {
// error handling and cleanup omitted for brevity
}
struct stat st;
fstat(fileno(fp), amp;st); // Error check omitted
char buffer[st.st_size 1];
fread(buffer, sizeof(char), st.st_size, fp);
buffer[st.st_size] = '';
fprintf(stderr, "%sn", *buffer);
fclose(fp);
Комментарии:
1. Осторожно.. кто-то может случайно или злонамеренно передать вам двоичный файл. Так что же такое ‘%s’. Никогда не предполагайте, что входные данные соответствуют вашим ожиданиям!