Я так запутался в 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
}
}
}
Что произойдет, если getline не работает (например, входной поток недействителен или пользователь делает ctrl-c без ввода)?
getline вернет -1, и вы потерпите крах.
s
достаточно большим , чтобы вместитьsizeToCopy+1
байт.memcpy
безоговорочно запишет столько байтов в буфер. Еслиs
слишком мало, вы можете получить SEGFAULT. Даже не ясно, чтоs
является действительным указателем памяти в этом отношении.std::string
вместо строк в стиле C.