使用10月2日发布的Symbian S60第5版SDK,我正在编译/运行(在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标准的代码可能会有什么替换功能? (这应该是一个跨平台的库)
感谢。
答案 0 :(得分:1)
对我来说,这似乎是一个步入vswprintf()
电话的工作。即使您只能进行汇编级调试,也应该清楚通过监视str[]
内存中的内容来进行更多或更少的操作。
答案 1 :(得分:1)
我碰巧在vswprintf的实现中找到了一个内部缓冲区,硬编码为128字节。这很可能会导致长字符串崩溃。
答案 2 :(得分:0)
将%S更改为%s - 将大写更改为小写。
在基于MS的printfs中,%S表示unicode字符,因此这就是123字符串失败的原因,它预计每个字符有2个字节。 (注意%S不是标准的一部分,因此这里的Symbian可能不同)
实际上,我认为这仍然适用于Symbian。
答案 3 :(得分:0)
您可以尝试将%S
格式说明符更改为%ls
。正如我之前的评论中所提到的,它们应该是等价的,但实现中可能存在错误。请注意,vswprintf
函数是在C99标准中定义的,因为还没有任何完全符合C99的编译器(我相信),vswprintf
的任何给定实现很可能不完全符合规范,或者它包含错误(前者比后者更可能)。
答案 4 :(得分:0)
你可以尝试不调用test()并使用swprintf - 如果bug与VARARGS处理有关吗?
答案 5 :(得分:0)
我现在通过使用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);
}
(在这种情况下,你实际上必须use %s)