Ошибка сегментации при использовании `getopt_long` с нераспознанным параметром long

#c #pointers #segmentation-fault

#c #указатели #ошибка сегментации

Вопрос:

Я использую getopt_long функцию в моей новой программе. Он работает нормально при передаче допустимого параметра long. Но если я попытаюсь вызвать программу с недопустимым параметром, т.е. --unknown , выполнение останавливается, сообщая, что произошла ошибка сегментации. Полная команда program version --unknown .

Где мне нужно изменить код, чтобы моя программа снова заработала? (Примечание: это нормально при передаче недопустимого параметра short)

Это для программы командной строки. Ему необходимо получать подкоманды в качестве первого аргумента и параметры, специфичные для каждой подкоманды. Я хотел добавить поддержку длинных параметров, потому что работать с короткими действительно сложно.

 char* subcommand = /* ... */;
int option_char = 0;
int exit_code = 0;

/* ... */
// Note: argv should be an array of strings containing the command-line arguments
int pm_parse_arguments(int argc, char** argv) {
    opterr = 0;
    if(strcmp(subcommand, "version") == 0) {
        return pm_parse_version_arguments(argc, argv);
    } else {
        // No recognized subcommand
        pm_global_unrecognized_subcommand(subcommand);
    }
    return exit_code;
}

int pm_parse_version_arguments(int argc, char** argv) {
    // List of long options
    struct option long_options[] = {
        {"help",        no_argument, 0, 'h'},
        {"major",       no_argument, 0, 'm'},
        {"minor",       no_argument, 0, 0},
        {"revision",    no_argument, 0, 'r'},
    };

    // Index of option
    int option_index = 0;

    while((option_char = getopt_long(argc, argv, ":hmr", long_options, amp;option_index)) != -1) {
        switch(option_char) {
            /* ... */
        }
    return exit_code;
}
  

Он должен выводиться Unrecognized option: --unknown при передаче параметра long --unknown , как и для коротких. Вместо этого возвращается ошибка сегментации.

Вот полный журнал вывода Valgrind в подробном режиме.

Ответ №1:

getopt_long требуется, чтобы массив параметров long завершался структурой параметров с нулевым значением (аналогично тому, как строки завершаются нулевым значением). В противном случае он не знал бы, сколько их было.

Комментарии:

1. Я добавил обнуленную структуру options в массив long options, и это решило мою проблему с ошибкой сегментации, спасибо! Обратите внимание, что вместо структуры с обнуленными параметрами может использоваться нулевая структура .

2. Это не «нулевая структура»; в C. NULL определяется как 0 , которая инициализируется нулем.