LINUX.ORG.RU

Ошибка сегментирования

 ,


1

4
#include <argp.h>
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <cerrno>
using namespace std;

namespace arg_pars
{
  struct Res {double ext{-1}; vector<string> datfiles;};
  static argp_option options = {"ext", 'e', "{1 | 2 | 2.6 | 4.2}", 0, "level"};
  static error_t cb(int key, char *arg, struct argp_state *state)
  {
    switch (key)
      {
      case 'e':
        /**/
        break;
      case ARGP_KEY_ARG:
        reinterpret_cast<Res*>(state->input)->datfiles.emplace_back(arg);
        break;
      case ARGP_KEY_SUCCESS:
        break;
      default:
        return ARGP_ERR_UNKNOWN;
      }
    return 0;
  }
  static argp parser = {&options, cb};
}
int main(int argc, char **argv)
{
   arg_pars::Res res;
   error_t er = argp_parse(&arg_pars::parser, argc, argv, 0, NULL, &res);
   cout << "ok\n";
}
$ g++ t.cpp -std=c++14
$ ./a.out
Ошибка сегментирования
$ g++ --version
g++ (Gentoo 5.4.0-r3 p1.3, pie-0.6.5) 5.4.0
x32

Если вместо vector<string> использовать struct D{char[20]}; vector<D> datfiles; например, то всё нормально. Ошибка комплилятора, верно?

★★

Последнее исправление: beastie (всего исправлений: 2)

Ответ на: комментарий от pavlick

Поймать падение под gdb не позволяет чсв? Или это конкурс поставь диагноз по фотографии пациента из паспорта?

iliyap ★★★★★
()

А если вместо reinterpret_cast<> воткнуть static_cast<>, то нормально? Ну и бэктрейс давай.

DELIRIUM ☆☆☆☆☆
()

Какой отвратительный код...

invy ★★★★★
()

argp_parse(&arg_pars::parser, argc, argv, 0, NULL, &res);

static error_t cb(int key, char *arg, struct argp_state *state)

emplace_back(arg); // arg == null

invy ★★★★★
()
Ответ на: комментарий от invy

Нет

if(arg == NULL)
   cout << "null\n";
else
   reinterpret_cast<Res*>(state->input)->datfiles.push_back(arg);
аналогично.
error_t argp_parse (const struct argp *ARGP, int ARGC,
          char **ARGV, unsigned FLAGS, int *ARG_INDEX, void *INPUT )

DELIRIUM, замена reinterpret_cast на статик каст не помогает.

pavlick ★★
() автор топика
Последнее исправление: pavlick (всего исправлений: 1)
Ответ на: комментарий от pavlick

Если ((Res*)(state->input) не помогает, то бери дебагер и ищи где ошибка. Скорее всегд где-то либо у тебя либо в этом гнутом поделии.

И вообще не используй эту гадость. И не используй такие отступы кривые - читать невозможно.

invy ★★★★★
()
$ g++ -std=c++14 a.cc -o a -Wall -O -ggdb && gdb ./a

(gdb) bt
#0  __strcmp_sse2 () at ../sysdeps/x86_64/multiarch/../strcmp.S:174
#1  0x00000031b54f36a0 in find_long_option (name=0x1002 <error: Cannot access memory at address 0x1002>, long_options=0x614d08) at argp-parse.c:204
#2  convert_options (argp=0x6020c0 <arg_pars::parser>, parent=parent@entry=0x0, parent_index=parent_index@entry=0, group=0x614c20, 
    cvt=cvt@entry=0x7fffffffd2c0) at argp-parse.c:349
#3  0x00000031b54f388d in convert_options (argp=argp@entry=0x7fffffffd160, parent=parent@entry=0x0, parent_index=parent_index@entry=0, group=<optimized out>, 
    cvt=cvt@entry=0x7fffffffd2c0) at argp-parse.c:406
#4  0x00000031b54f3be4 in parser_convert (flags=0, argp=0x7fffffffd160, parser=0x7fffffffd2e0) at argp-parse.c:435
#5  parser_init (input=0x7fffffffd400, flags=0, argv=0x7fffffffd508, argc=1, argp=0x7fffffffd160, parser=0x7fffffffd2e0) at argp-parse.c:515
#6  __argp_parse (argp=0x7fffffffd160, argp@entry=0x6020c0 <arg_pars::parser>, argc=1, argv=0x7fffffffd508, flags=flags@entry=0, 
    end_index=end_index@entry=0x0, input=input@entry=0x7fffffffd400) at argp-parse.c:915
#7  0x0000000000400c00 in main (argc=<optimized out>, argv=<optimized out>) at a.cc:35

https://www.gnu.org/software/libc/manual/html_node/Argp-Option-Vectors.html#A...

The options field in a struct argp points to a vector of struct argp_option structures, each of which specifies an option that the argp parser supports. Multiple entries may be used for a single option provided it has multiple names. This should be terminated by an entry with zero in all fields. Note that when using an initialized C array for options, writing { 0 } is enough to achieve this.

diff --git a/a.cc b/a.cc
index 7afa384..ea88c30 100644
--- a/a.cc
+++ b/a.cc
@@ -11,3 +11,3 @@ namespace arg_pars
   struct Res {double ext{-1}; vector<string> datfiles;};
-  static argp_option options = {"ext", 'e', "{1 | 2 | 2.6 | 4.2}", 0, "level"};
+  static argp_option options[] = {{"ext", 'e', "{1 | 2 | 2.6 | 4.2}", 0, "level"}, {0}};
   static error_t cb(int key, char *arg, struct argp_state *state)
@@ -29,3 +29,3 @@ namespace arg_pars
   }
-  static argp parser = {&options, cb};
+  static argp parser = {options, cb};

sf ★★★
()
Ответ на: комментарий от sf

Огромное спасибо. Точно, сам накосячил. Переписал так:

static argp_option options[] = { {"ext", 'e', "{1 | 2 | 2.6 | 4.2}", 0, "level"}, {0} };
Работает нормально.

pavlick ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.