vswprintf вылетает - PullRequest
       21

vswprintf вылетает

0 голосов
/ 18 октября 2008

с использованием Symbian S60 5th edition SDK, выпущенного 2 октября, я компилирую / запускаю (на sim) следующий фрагмент кода:

void test(wchar_t *dest, int size, const wchar_t *fmt, ...) {
    va_list vl;
    va_start(vl, fmt);
    vswprintf(dest, size, fmt, vl);
    va_end(vl);
}

...

wchar_t str[1024];

// this crashes (2nd string 123 characters (+ \0) equals 248 bytes)
test(str, 1024, L"msg: %S", L"this is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a tes");

// this works (2nd string 122 characters (+ \0) equals 246 bytes)
test(str, 1024, L"msg: %S", L"this is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a te");

Безо всякой очевидной для меня причины (даже после прочтения справочной страницы vswprintf сто раз) я могу выяснить, почему этот код вызывает сбой при вызове vswprintf длинных строк :-( точно такой же код прекрасно работает на Linux-боксе. Для str выделено достаточно памяти, плюс vswprintf все равно проверяет переполнение буфера. К сожалению ... Отладчик S60 не прерывается в этом сбое, поэтому у меня нет подробностей: - (

У кого-нибудь есть идеи?

Если предположить ошибку в подпрограмме Symbian vswprintf, какие возможны замены функций с использованием кода, совместимого с POSIX? (предполагается, что это кроссплатформенная библиотека)

Спасибо.

Ответы [ 6 ]

1 голос
/ 19 августа 2010

Мне удалось найти внутренний буфер внутри реализации vswprintf, который жестко запрограммирован в 128 байтов. Это вполне может вызвать такой сбой на длинных струнах.

1 голос
/ 18 октября 2008

Для меня это похоже на работу по входу в vswprintf() вызов. Даже если вы можете выполнять только отладку на уровне сборки, должно быть ясно, что происходит более или менее, следя за тем, что происходит в памяти str[].

0 голосов
/ 19 октября 2008

Я теперь «решил» эту проблему, используя функции Symbian для выполнения этой задачи:

void test(wchar_t *dest, int size, const wchar_t *fmt, ...) {
    VA_LIST args;
    VA_START(args, fmt);

    TPtrC16 fmtPtr((const TUint16*)fmt, wcslen(fmt) + 1);  
    TPtr16  targetPtr((TUint16*)dest, size);

    targetPtr.FormatList(fmtPtr, args);
    targetPtr.ZeroTerminate();

    VA_END(args);
}

(в этом случае вам действительно нужно использовать% s )

0 голосов
/ 18 октября 2008

Можете ли вы попробовать не вызывать test () и использовать вместо него swprintf - если ошибка связана с обработкой VARARGS?

0 голосов
/ 18 октября 2008

Вы можете попробовать изменить спецификатор формата %S на %ls. Как упоминалось в моем предыдущем комментарии, они должны быть эквивалентны, но в реализации может быть ошибка. Обратите внимание, что функция vswprintf определена в стандарте C99, и, поскольку еще нет полностью соответствующих компиляторов C99 (я полагаю), вполне возможно, что любая конкретная реализация vswprintf не полностью соответствует спецификации, или что он содержит ошибки (первый более вероятен, чем второй).

0 голосов
/ 18 октября 2008

Измените% S на% s - заглавными и строчными.

В основанных на MS printfs% S означает символы в кодировке Юникод, поэтому в 123-символьной строке происходит сбой, ожидается 2 байта на символ. (обратите внимание, что% S не является частью стандарта, поэтому Symbian здесь может отличаться)

На самом деле, я думаю, что это относится и к Symbian .

...