Иногда получаю ошибку сегментации

0

Я так запутался в SEGFAULT в моей программе. Я пытаюсь реализовать scanf. Поэтому я передаю const char в качестве первого параметра, чем проанализирую его для% entries и чем использовать аргументы переменных для хранения в нем значения.
Я так смущен этим.
Я не являюсь экспертом в программировании C++. Но я понимаю распределение и использование памяти. Вот мой фрагмент кода. Я использую getline, передавая ему NULL-указатель на char и 0 как размер. Согласно руководству, он должен хранить память malloc самостоятельно.
Я думаю, что это плохая идея, что некоторые func выделяют память. Но пусть считают, что все в порядке.
Поскольку этот func имеет память malloc, поэтому я должен освободить его, но когда я пытаюсь это сделать, у меня возникает ошибка сегментации, но если я оставлю это как есть, утечки памяти в программе нет. Я использую valgrind для проверки утечек памяти.

Альтернативно, перед вызовом getline(), * lineptr может содержать указатель на буфер malloc (3) -allocated * n байтов в размере. Если буфер не достаточно велик, чтобы удерживать строку, getline() изменяет его размер с помощью realloc (3), обновляя * lineptr и * n при необходимости.

Вот мой фрагмент кода.

s = va_arg(argp, char *);
                if (lengthIsSet) {
                    size_t newLen ;
                    size_t readLen;
                    char *strInput = NULL;
                    length = atoi(lengthStr.c_str());
                    readLen = getline (&strInput,&newLen,inputSteam);
                   if (!strInput) {
                       break;
                   }                 
                   int sizeToCopy = (length<readLen)?length:readLen;
                   memcpy(s,strInput,sizeToCopy+1);
                   s[sizeToCopy] = '\0';
}

Я попытался инициализировать size_t newLen = 0; он, похоже, работает, но я не думаю, что это вызывает проблему. Пожалуйста, помогите решить эту проблему. Я был бы очень благодарен за любую помощь и объяснение.

РЕДАКТИРОВАТЬ

Пожалуйста, предложите правильно прочитать ввод данных пользователя с помощью C++. Без использования явно scanf, vscanf и т.д. Пожалуйста, помогите, потому что я много часов занимаюсь этой проблемой. Я нашел только эти функции для чтения пользовательского ввода из потока. Возможно, есть хороший способ сделать это с помощью функций C++. Я не про в C++ и C, поэтому не знаю много возможностей.

EDIT 2

void scanfCustom(const char* input, FILE *inputSteam, va_list argp) {
    const char *p;
    int * i;
    bool formFound = false;
    std::string lengthStr("");
    int length;
    bool lengthIsSet = false;
    unsigned u;
    char *s;
     p = input;
         for (; *p != '\0'; p++) {
        if ((formFound) && ( *p >= '0' && *p <= '9' ) ) {
                lengthStr+=(*p);
                lengthIsSet = true;
                continue;
             }
        if (*p == '%') {
            formFound = true;
            continue;
        }   
        formFound = false;
        switch (*p) {
            case 's':  
                 s = va_arg(argp, char *);
                if (lengthIsSet) {
                    size_t newLen = 0;
                    size_t readLen;
                    char *strInput = NULL;
                    length = atoi(lengthStr.c_str());
                    readLen = getline (&strInput,&newLen,inputSteam);
                   if (!strInput) {
                       break;
                   }                 
                   int sizeToCopy = (length<readLen)?length:readLen;
                   memcpy(s,strInput,sizeToCopy+1);
                   s[sizeToCopy] = '\0';
                   // free(strInput);
                   //fgets(s,length,inputSteam);
                }
//TODO READ FULL STR
        }
    }
}
  • 1
    Трудно сказать из вашего фрагмента кода ли буфер s достаточно большим , чтобы вместить sizeToCopy+1 байт. memcpy безоговорочно запишет столько байтов в буфер. Если s слишком мало, вы можете получить SEGFAULT. Даже не ясно, что s является действительным указателем памяти в этом отношении.
  • 1
    Вы можете уменьшить количество вхождений SEGFAULT, используя std::string вместо строк в стиле C.
Показать ещё 4 комментария
Теги:
pointers
memory
memory-management

1 ответ

0

Что произойдет, если getline не работает (например, входной поток недействителен или пользователь делает ctrl-c без ввода)?

getline вернет -1, и вы потерпите крах.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню