#c #visual-studio #segmentation-fault #android-ndk #porting
#c #visual-studio #ошибка сегментации #android-ndk #перенос
Вопрос:
У меня есть проект Visual Studio, который я переношу на Android. Я сталкиваюсь с проблемой ошибки сегментации при вызовах функций, которая напоминает функции ниже:
char* format1(const char* fmt, ...) {
char* buf = new char[1030];
va_list ap;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
return buf;
}
char* format2(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
char* s = format1(fmt, ap);
va_end(ap);
return s;
}
Вызов функций выглядит следующим образом:
char* s = format2("%*.*d", 8, 8, 9910153);
У меня есть пара запросов относительно вышеизложенного:
Если я пройдусь по коду в gdb для вызова ‘function2’, он покажет: format (fmt = 0x4) Почему это так?
Когда вызывается ‘function1’, gdb показывает: format1 (fmt = 0x15be30 «некоторое случайное значение в памяти») Как получилось, что значение fmt изменилось? Кроме того, в зависимости от значения в fmt второй вызов приводит к ошибке сегментации.
Любая помощь в объяснении приведенного выше поведения была бы весьма признательна.
Комментарии:
1. Просто передайте
ap
как ava_list
или используйтеva_arg
для его извлечения.
Ответ №1:
format1
принимает переменный набор аргументов, а не a va_list
; вы передаете ему один (нецелочисленный) аргумент, а строка формата ожидает три целочисленных аргумента, поэтому возникает неопределенное поведение.
Это должно быть что-то вроде:
char* format1(const char* fmt, va_list ap) {
char* buf = new char[1030];
vsprintf(buf, fmt, ap);
return buf;
}
Комментарии:
1. Это не отвечает на вопрос, в котором спрашивалось, почему отладчик сообщает fmt=0x4. Неопределенное поведение
vsnprintf
не может вызвать это, потому что функция еще не была вызвана.2. @RobKennedy: Я отвечаю на вопрос в названии: почему существует ошибка сегментации? Я понятия не имею, как именно конкретный отладчик может вести себя при повреждении стека.
3. При входе в
format2
(и действительно, даже при входе вformat1
) повреждение стека еще не произошло. Этого не происходит, покаvsnprintf
не будет вызвано.4. @MikeSeymour: Спасибо, я пропустил определение аргумента (случай неаккуратного копирования вставки). Но отображение gdb действительно сбивает с толку, потому что его отображение продолжает отвлекать мое внимание! Любое объяснение отображения gdb? Должен ли я задать это как другой вопрос?