Я набрал это раньше, но отложил публикацию, так как не смог найти в вашем коде ничего, что могло бы вызвать нарушение прав доступа.Но теперь, когда вы определили проблему.Я думал, что подытожу, что я и другие нашли неправильно с вашим кодом.Обратите внимание, что большинство моих наблюдений - это в основном предпочтения стиля, а не то, что вы действительно сделали что-то не так.
Гера - это описание проблем, которые я вижу в вашем коде.
Обработка ошибок файла
Поскольку ваша подпрограмма должна возвращать адрес указателя, вы должны возвращать значение NULL при возникновении ошибки.Это сигнализирует вызывающей стороне, которая должна проверять наличие нулей, что что-то пошло не так.Также рассмотрите возможность использования функции perror () .Наряду с отображением сообщения, которое вы предоставляете, оно также добавит текст причины ошибки ввода-вывода.
if (fp)
{
perror("failed to open file for reading.");
return NULL;
}
Пример вывода при ошибке открытия:
failed to open file for reading: file not found.
MAX_LINE_SIZE иЗначения ROW
Переменная, используемая для чтения каждой строки, должна иметь размер только самой длинной строки в файле плюс 2 байта, которые представляют терминатор строки и нулевой символ (см. документация fgets ).Не следует устанавливать максимальное количество строк, содержащихся в файле.Вы можете увеличить его, но 100000 слишком велико.Не зная ваших данных, вы должны рассмотреть что-то меньшее, например, 1024. ROW должен быть установлен на макс. Строки, ожидаемые для чтения.
#define MAX_LINE_SIZE 1024
#define ROW 100000
Обработка ошибок распределения
Всегда проверяйте, была ли процедура распределения успешной.Опять же, поскольку вызывающий должен проверять наличие нулей, если обнаружены какие-либо ошибки, прервитесь с нулевым возвращаемым значением.
arr = (int **)malloc(sizeof(int *) * ROW);
if ( arr == NULL ) return NULL;
и здесь
arr[row] = (int *)malloc(sizeof(int) * column);
if ( arr[row] == NULL ) return NULL;
Обрезать дополнительный символдобавлено fgets ()
Есть много способов сделать это, но вы должны удалить терминатор строки из ваших данных.Ниже приведено одно предложение для этого:
if ( strlen(line) > 0 ) line[strlen(line)-1] = 0;
Группировка операторов
Попробуйте сгруппировать операторы, выполняющие определенную задачу, вместе.Это облегчит чтение вашего кода.
Пример 1. Логика размещения столбцов
column = countComma(line) +1;
arr[row] = (int *)malloc(sizeof(int) * column);
len[row] = column;
Пример 2. Логика анализа строк
column = 0;
result = strtok(line, ",");
while ( result != NULL ) {
arr[row][column] = atoi(result);
//printf("%d\t", arr[row][column]);
result = strtok(NULL, ",");
column++;
}
strtok returnвведите
Вы должны были получить предупреждение за это, но «результат» должен быть определен как указатель на символ, а не указатель на int.(см. документация strtok )
char *result = NULL;
Как уже упоминалось в моем комментарии ниже, моя версия вашего кода работала нормально без большинства этих предложений.Предложения здесь - только мои наблюдения и мнения.При рассмотрении любого из этих предложений используйте свое собственное суждение.