Сохранение argv[1] в переменную char* вызывает ошибку seg при передаче в отдельную функцию
Я пытаюсь переписать урезанную версию команды "ls" в C. У меня изначально все было сделано в моем main()
которая работала нормально и не привела к ошибкам сегмента. Буквально все, что я делал, это копировал и вставлял основную часть моего основного текста в новую функцию, которую я назвал into_array()
(чтобы сделать фактическое сохранение записей каталога в мой собственный самодельный file_info
структуры, которые будут проанализированы позже). Теперь, когда я пытаюсь запустить код солнечного дня - просто a.out /home
который должен сортировать и печатать имена, я получаю полный отсортированный список, за которым следует ошибка сегмента, и так как единственное, что я изменил, это прямое использование argv[1]
к использованию char *pathname
Я предполагаю, что это как-то связано с этим. Ниже приведен код:
void into_array (char *arg)
{
//asume correct input, default
DIR *myDIR;
struct dirent *mydirent;
struct stat *mystat;
myDIR = opendir(arg);
int count = 0;
while ((mydirent = readdir(myDIR)) != NULL)
{
count++;
}
rewinddir(myDIR);
struct file_info **file_info_array = malloc(sizeof(struct file_info*)*count);
int i = 0;
while ((mydirent = readdir(myDIR)) != NULL)
{
stat(arg, mystat);
file_info_array[i] = malloc(sizeof(struct file_info));
struct file_info *file_i = info_store(mydirent, mystat, 's');
file_info_array[i] = file_i;
i++;
}
file_info_array[i] = NULL;
int is_closed = closedir(myDIR);
send_to_sort(file_info_array, 'n');
print(file_info_array);
}
int main (int argc, char *argv[])
{
into_array(argv[1]);
return 0;
}
2 ответа
Это не может работать:
struct stat *mystat;
...
stat(arg, mystat)
stat
требует указатель на хранилище, где он может хранить результат, mystat
не инициализирован. Проще всего сделать
struct stat mystat;
stat(arg, &mystat)
Вы пишете мимо вашего массива с file_info_array[i] = NULL;
, Вы не выделили память для этого последнего элемента, вы должны выделить память для count + 1
элементы, если вам нужно, чтобы последний элемент был нулевым указателем.
Другие вещи, которые вам нужно сделать, в противном случае вы настраиваете себя на то, чтобы не понять, что происходит, когда ваш код не работает:
- opendir () может потерпеть неудачу, убедитесь, что он успешен.
- stat () может потерпеть неудачу, убедитесь, что вы добились успеха.
- malloc () может завершиться ошибкой, убедитесь, что вы проверите его.
- Кто-то может не передать аргумент вашей программе, проверьте это.
- Есть вероятность, что в других ваших функциях одинаково много ошибок, вы должны их тоже проверять.
То, что ваша оригинальная программа не имела сегфолта, не доказывает, что она была полностью правильной. Если он демонстрирует неопределенное поведение, то такое поведение может оказаться именно таким, на которое вы надеялись и ожидали, но вы не можете полагаться на то, что оно будет одинаковым при запуске к запуску, тем более после изменения кода (без разрешения UB).).
Ваша программа содержит вызовы нескольких функций, определения которых вы не предоставляете. Любой из них может вызвать UB. Однако предоставленная вами функция, безусловно , вызывает UB: она записывает после конца динамического массива file_info_array
потому что вы выделяете достаточно места для всех записей, но не для NULL в конце.
Как впервые заметил @nos, у вас также есть проблема, связанная с переменной mystat
и вы очень оптимистично кодируете, предполагая, что программные аргументы верны, и что ни один из ваших вызовов функций не выполнен.