Ошибки в valgrind при чтении файла - C

Итак, мне трудно понять, в чем смысл ошибок, которые мне дает valgrind.

Мой код получает файл судоку и проверяет его правильность или нет. Он получает имя файла в командной строке, открывает его и делает все, что должен, а именно проверяет его правильность.

Пример:

./run sudoku.txt

Код работает абсолютно нормально, но когда я запустил valgrind, он выдал две ошибки, которые я вообще не понял, но я предположил, что это связано с обработкой файлов.

Вот запуск valgrind:

==20853== Syscall param openat(filename) points to unaddressable byte(s)
==20853==    at 0x4F4BD9E: open (open64.c:47)
==20853==    by 0x4EC85F9: _IO_file_open (fileops.c:189)
==20853==    by 0x4EC85F9: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:281)
==20853==    by 0x4EBAF19: __fopen_internal (iofopen.c:78)
==20853==    by 0x4EBAF19: fopen@@GLIBC_2.2.5 (iofopen.c:89)
==20853==    by 0x108BD1: main (q1_acs2.c:90)
==20853==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==20853== 
==20853== Invalid read of size 4
==20853==    at 0x4EB82BD: __isoc99_fscanf (isoc99_fscanf.c:30)
==20853==    by 0x108D4E: main (q1_acs2.c:96)
==20853==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==20853== 
==20853== 
==20853== Process terminating with default action of signal 11 (SIGSEGV)
==20853==  Access not within mapped region at address 0x0
==20853==    at 0x4EB82BD: __isoc99_fscanf (isoc99_fscanf.c:30)
==20853==    by 0x108D4E: main (q1_acs2.c:96)
==20853==  If you believe this happened as a result of a stack
==20853==  overflow in your program's main thread (unlikely but
==20853==  possible), you can try to increase the size of the
==20853==  main thread stack using the --main-stacksize= flag.
==20853==  The main thread stack size used in this run was 8388608.
==20853== 
==20853== HEAP SUMMARY:
==20853==     in use at exit: 0 bytes in 0 blocks
==20853==   total heap usage: 1 allocs, 1 frees, 552 bytes allocated
==20853== 
==20853== All heap blocks were freed -- no leaks are possible
==20853== 
==20853== For counts of detected and suppressed errors, rerun with: -v
==20853== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation Fault

А вот часть моего кода, где я открываю файл и сохраняю его в матрице: (Я добавлю номера строк, чтобы вы могли видеть, где они указывают на ошибки)

85 int main(int argc, char *argv[])
86 {
87 int r = 9, c = 9, flag = 0;
88 FILE *px;
89
90 px = fopen(argv[1], "r");
91 int mat[r][c];
92
93 for (int i = 0; i < r; i++) {
94  for (int j = 0; j < c; j++)
95      if (j < 8)
96          fscanf(px, "%d,", &mat[i][j]);
97      else
98          fscanf(px, "%d", &mat[i][j]);
99 }
100 fclose(px);

Проверьте указатель файла после fopen(). Проблема с файлом (от Valgrind).

Krishna Kanth Yenumula 13.12.2020 04:53

В чем смысл заявления if (j <8)? Вы делаете то же самое в if и else.

Barmar 13.12.2020 04:58

@Barmar: числа в строке разделяются запятыми. Для всех, кроме последнего, тоже читайте запятую. Хотя вы можете обойтись без буквального совпадения запятой с последним числом в строке (у fscanf() нет возможности сообщить об этом с помощью формата "%d,"), это довольно тонко. На самом деле, вы бы сошли с рук с данными, разделенными пробелами или запятыми (или смесью), как они есть, если в конце строки нет запятой.

Jonathan Leffler 13.12.2020 05:01

Почему бы не прочитать всю строку в формате "%d,%d,%d,%d,%d,%d,%d,%d,%d"?

Barmar 13.12.2020 05:11

@JonathanLeffler да, это все

Rhyno 13.12.2020 05:12

Я ПОНЯЛ, В ЧЕМ БЫЛА ПРОБЛЕМА. Это было так глупо... я немного смущен. Я забыл запустить valgrind с именем файла. Так что я должен был запустить как: valgrind ./run sudoku.txt Тот, кто заставил меня найти глупую проблему, был @JonathanLeffler, спасибо! Спасибо всем, кто прокомментировал

Rhyno 13.12.2020 05:17
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
422
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Несмотря на то, что вы предлагаете в тексте, вывод Valgrind показывает, что вы не передали аргумент в программу. Вы не проверили, что argv[1] допустимо, прежде чем передать его fopen(). Поскольку вы пропустили аргумент имени файла, argv[1] является нулевым указателем, и система возражает против вас, используя нулевой указатель.

==20853==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

Нулевой указатель... В ошибках сообщается обо всех упоминаниях «адрес 0x0»; ваш код не выполняет соответствующую проверку ошибок.

Вы также не проверяете, что fopen() удалось, что вызовет проблемы, если данный файл не открывается. Вы также не проверяете успешность вызовов fscanf(); это тоже может вызвать проблемы, если содержимое файла не соответствует вашим ожиданиям.

Если, как вы утверждаете, вы передали имя файла программе, вы увидите его в верхней части вывода Valgrind. Вы не показали эту информацию.

argv[1] — это «sudoku.txt»

John3136 13.12.2020 04:54

@ John3136: так говорит ОП. Вальгринд говорит иначе.

Jonathan Leffler 13.12.2020 04:55

@JonathanLeffler Чувак, я действительно смущен. Я забыл запустить valgrind с именем файла... Не знаю, гнилой ли у меня мозг, но знаете, бывает. Большое спасибо, вы тот, кто заставил меня узнать это! Я поставлю ваш ответ как правильный ответ!

Rhyno 13.12.2020 05:19

@RhynoProgrammin — всякое бывает. Пусть первыми бросят камни те, кто никогда не совершал подобной ошибки. Теперь вы знаете, почему вы выполняете проверку ошибок в своем коде.

Jonathan Leffler 13.12.2020 05:20

Да, именно. Еще раз спасибо, @JonathanLeffler!.

Rhyno 13.12.2020 05:24

Я думаю, вы пропустили проверку возвращаемого значения fscanf; поместите это в утверждение if:

if (fscanf(fp, "%d", &value) == 1)

Затем результат будет проверен и не будет расширяться целым числом.

Первая зарегистрированная ошибка связана с fopen(). Проблема, связанная с fscanf(), заключается в передаче нулевого указателя в качестве файлового потока.

Jonathan Leffler 13.12.2020 04:59

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