Code Bye

C++中字符流操作函数setfill()和setw()造成程序跑飞的问题

最近做的程序中需要字符做一些转换,例如将1变成01会用到如下代码:
	wstringstream wstrStream;
    wstrStream<<setfill(L"0")<<setw(2)<<1;
	wcout<<wstrStream.str()<<endl;

这段代码在PC环境下没有问题。
但是前两行代码运行在嵌入式环境中,造成了程序跑飞,本人也是无语了。
下面是单步运行时的源码及汇编代码:

basic_ios.h:452:        _M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0)
200EA3D8 E28D6E51        ADD         r6,sp,#0x510
200EA3DC E2866008        ADD         r6,r6,#0x8
200EA3E0 E2860034        ADD         r0,r6,#0x34
200EA3E4 EB08BFA0        BL          2031A26C std::ios_base::ios_base 
200EA3E8 E59F3540        LDR         r3,200EA930
200EA3EC E58D354C        STR         r3,[sp,#0x54C]
200EA3F0 E3A01000        MOV         r1,#0x0
200EA3F4 E58D15BC        STR         r1,[sp,#0x5BC]
200EA3F8 E58D15C0        STR         r1,[sp,#0x5C0]
200EA3FC E5CD15C4        STRB        r1,[sp,#0x5C4]
200EA400 E58D15C8        STR         r1,[sp,#0x5C8]
200EA404 E58D15CC        STR         r1,[sp,#0x5CC]
200EA408 E58D15D0        STR         r1,[sp,#0x5D0]
200EA40C E58D15D4        STR         r1,[sp,#0x5D4]
istream:582:      : _M_gcount(streamsize(0))
200EA410 E3043710        MOVW        r3,#0x4710
200EA414 E34231A6        MOVT        r3,#0x21A6
200EA418 E5937008        LDR         r7,[r3,#0x8]
200EA41C E58D7518        STR         r7,[sp,#0x518]
200EA420 E1A0B006        MOV         r11,r6
200EA424 E1A06007        MOV         r6,r7
200EA428 E593A00C        LDR         r10,[r3,#0x0C]
200EA42C E536300C        LDR         r3,[r6,#-0x0C]!
200EA430 E78BA003        STR         r10,[r11,r3]
200EA434 E58D151C        STR         r1,[sp,#0x51C]
istream:583:      { this->init(0); }
200EA438 E59D3518        LDR         r3,[sp,#0x518]
200EA43C E513000C        LDR         r0,[r3,#-0x0C]
200EA440 E08B0000        ADD         r0,r11,r0
200EA444 EBFF3AC5        BL          200B8F60 std::basic_ios<wchar_t,std::char_traits<wchar_t>_>::init 
200EA448 EA000001        B           200EA454
200EA44C E1A04000        MOV         r4,r0
200EA450 EA000042        B           200EA560
ostream:362:      { this->init(0); }
200EA454 E3043710        MOVW        r3,#0x4710
200EA458 E34231A6        MOVT        r3,#0x21A6
200EA45C E5932010        LDR         r2,[r3,#0x10]
200EA460 E58D2520        STR         r2,[sp,#0x520]
200EA464 E28D8E52        ADD         r8,sp,#0x520
200EA468 E512200C        LDR         r2,[r2,#-0x0C]
200EA46C E5933014        LDR         r3,[r3,#0x14]
200EA470 E7883002        STR         r3,[r8,r2]
200EA474 E59D3520        LDR         r3,[sp,#0x520]
200EA478 E513000C        LDR         r0,[r3,#-0x0C]
200EA47C E0880000        ADD         r0,r8,r0
200EA480 E3A01000        MOV         r1,#0x0
200EA484 EBFF3AB5        BL          200B8F60 std::basic_ios<wchar_t,std::char_traits<wchar_t>_>::init 
200EA488 EA000006        B           200EA4A8
200EA48C E1A04000        MOV         r4,r0
istream:102:      { _M_gcount = streamsize(0); }
200EA490 E58D7518        STR         r7,[sp,#0x518]
200EA494 E5963000        LDR         r3,[r6]
200EA498 E78BA003        STR         r10,[r11,r3]
200EA49C E3A03000        MOV         r3,#0x0
200EA4A0 E58D351C        STR         r3,[sp,#0x51C]
200EA4A4 EA00002D        B           200EA560
istream:799:      : __istream_type(), __ostream_type() { }
200EA4A8 E3043710        MOVW        r3,#0x4710
200EA4AC E34231A6        MOVT        r3,#0x21A6
200EA4B0 E5932004        LDR         r2,[r3,#0x4]
200EA4B4 E58D2518        STR         r2,[sp,#0x518]
200EA4B8 E28D7E51        ADD         r7,sp,#0x510
200EA4BC E2877008        ADD         r7,r7,#0x8
200EA4C0 E512200C        LDR         r2,[r2,#-0x0C]
200EA4C4 E5933018        LDR         r3,[r3,#0x18]
200EA4C8 E7873002        STR         r3,[r7,r2]
sstream:511:      : __iostream_type(), _M_stringbuf(__m)
200EA4CC E59F3460        LDR         r3,200EA934
200EA4D0 E58D3518        STR         r3,[sp,#0x518]
200EA4D4 E2832028        ADD         r2,r3,#0x28
200EA4D8 E58D254C        STR         r2,[sp,#0x54C]
200EA4DC E2833014        ADD         r3,r3,#0x14
200EA4E0 E58D3520        STR         r3,[sp,#0x520]
streambuf:442:      _M_buf_locale(locale()) 
200EA4E4 E59F344C        LDR         r3,200EA938
200EA4E8 E58D3524        STR         r3,[sp,#0x524]
200EA4EC E3A03000        MOV         r3,#0x0
200EA4F0 E58D3528        STR         r3,[sp,#0x528]
200EA4F4 E58D352C        STR         r3,[sp,#0x52C]
200EA4F8 E58D3530        STR         r3,[sp,#0x530]
200EA4FC E58D3534        STR         r3,[sp,#0x534]
200EA500 E58D3538        STR         r3,[sp,#0x538]
200EA504 E58D353C        STR         r3,[sp,#0x53C]
200EA508 E2870028        ADD         r0,r7,#0x28
200EA50C EB08CA16        BL          2031CD6C std::locale::locale 
sstream:93:      : __streambuf_type(), _M_mode(__mode), _M_string()
200EA510 E59F3424        LDR         r3,200EA93C
200EA514 E58D3524        STR         r3,[sp,#0x524]
200EA518 E3A03018        MOV         r3,#0x18
200EA51C E58D3544        STR         r3,[sp,#0x544]
basic_string.h:2150:    : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
200EA520 E30369F0        MOVW        r6,#0x39F0
200EA524 E34A6051        MOVT        r6,#0x0A051
basic_string.h:255:        : _Alloc(__a), _M_p(__dat) { }
200EA528 E59F3410        LDR         r3,200EA940
200EA52C E58D3548        STR         r3,[sp,#0x548]
sstream:512:      { this->init(&_M_stringbuf); }
200EA530 E2870034        ADD         r0,r7,#0x34
200EA534 E287100C        ADD         r1,r7,#0x0C
200EA538 EBFF3A88        BL          200B8F60 std::basic_ios<wchar_t,std::char_traits<wchar_t>_>::init 
200EA53C EA00000D        B           200EA578
200EA540 E1A04000        MOV         r4,r0
200EA544 E28D0E52        ADD         r0,sp,#0x520
200EA548 E2800004        ADD         r0,r0,#0x4
200EA54C EBFF3C6E        BL          200B970C std::basic_stringbuf<wchar_t,std::char_traits<wchar_t>,...
200EA550 E28D0E51        ADD         r0,sp,#0x510
200EA554 E2800008        ADD         r0,r0,#0x8
200EA558 E59F13E4        LDR         r1,200EA944
200EA55C EBFF3782        BL          200B836C std::basic_iostream<wchar_t,std::char_traits<wchar_t>_>...
basic_ios.h:272:      ~basic_ios() { }
200EA560 E28D0E66        ADD         r0,sp,#0x660
200EA564 E59F33C4        LDR         r3,200EA930
200EA568 E5203114        STR         r3,[r0,#-0x114]!
200EA56C EB08BEFB        BL          2031A160 std::ios_base::~ios_base 
200EA570 E1A00004        MOV         r0,r4
200EA574 EB095C69        BL          20341720 __cxa_end_cleanup 
iomanip:189:      __os.fill(__f._M_c); 
200EA578 E59D3520        LDR         r3,[sp,#0x520]
200EA57C E513A00C        LDR         r10,[r3,#-0x0C]
200EA580 E088A00A        ADD         r10,r8,r10
basic_ios.h:362:        if (!_M_fill_init)
200EA584 E5DA3078        LDRB        r3,[r10,#0x78]
200EA588 E3530000        CMP         r3,#0x0
200EA58C 1A00000A        BNE         200EA5BC
basic_ios.h:440:      { return __check_facet(_M_ctype).widen(__c); }
200EA590 E59A0080        LDR         r0,[r10,#0x80]
basic_ios.h:48:      if (!__f)
200EA594 E3500000        CMP         r0,#0x0
200EA598 1A000000        BNE         200EA5A0
basic_ios.h:49:        __throw_bad_cast();
200EA59C EB08BB6B        BL          20319350 std::__throw_bad_cast    //error
locale_facets.h:287:      { return this->do_widen(__c); }
200EA5A0 E5903000        LDR         r3,[r0]
200EA5A4 E5933028        LDR         r3,[r3,#0x28]
200EA5A8 E3A01020        MOV         r1,#0x20
200EA5AC E12FFF33        BLX         r3
basic_ios.h:364:            _M_fill = this->widen(" ");
200EA5B0 E58A0074        STR         r0,[r10,#0x74]
basic_ios.h:365:            _M_fill_init = true;
200EA5B4 E3A03001        MOV         r3,#0x1
200EA5B8 E5CA3078        STRB        r3,[r10,#0x78]
basic_ios.h:383:        _M_fill = __ch;
200EA5BC E3A03030        MOV         r3,#0x30
200EA5C0 E58A3074        STR         r3,[r10,#0x74]
ios_base.h:660:      _M_width = __wide;
200EA5C4 E28D0E51        ADD         r0,sp,#0x510
200EA5C8 E2800008        ADD         r0,r0,#0x8
200EA5CC E59D3520        LDR         r3,[sp,#0x520]
200EA5D0 E513300C        LDR         r3,[r3,#-0x0C]
200EA5D4 E0803003        ADD         r3,r0,r3
200EA5D8 E3A02002        MOV         r2,#0x2
200EA5DC E5832010        STR         r2,[r3,#0x10]
test.cpp:144:    wstrStream<<setfill(L"0")<<setw(2)<<1;
200EA5E0 E2800008        ADD         r0,r0,#0x8
200EA5E4 E3A01001        MOV         r1,#0x1
200EA5E8 EB0002FC        BL          200EB1E0 std::basic_ostream<wchar_t,std::char_traits<wchar_t>_>:...

开始时候就是为wstrStream分配内存吧,怎么走到这一句就崩了呢?

200EA59C EB08BB6B        BL          20319350 std::__throw_bad_cast    //error

注意下面这句还没执行。

wstrStream<<setfill(L"0")<<setw(2)<<1;

所以本人又做了两次测试:
1.只定义一个变量

wstringstream wstrStream;

没问题!
2.不使用setfill 和setw

wstringstream wstrStream;
    wstrStream<<1;

也没问题!
所以问题应该出在setfill 和setw函数上,但是根据汇编报错的位置,不是setfill 和setw报的错啊!本人懵逼了。
也许本人汇编分析的不对,请各位帮看看!

解决方案

5

嵌入式不清楚
很多嵌入式没有操作系统
直接裸机跑
这样的话,假如主程序不是循环(一个几乎永远运行的循环)
那么由于程序跑飞的原因,最终也会形成循环执行
只是不知道你这里是啥情况,嵌入式用上了C++
应该跑在操作系统上了吧
这个操作系统有控制台么?

5

wstringstream 改成 wostringstream 试试?

10

理解讨论之前请先学会怎么样观察
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
对学习编程者的忠告:
多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建全部,然后在IDE中运行。(一般人本人不告诉他!
单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或在某行按F9设了断点后按F5执行停在该断点处的时候。
Windows:
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止
Linux:
进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件例如‘core.1234’
使用命令
gdb 运行程序名 core或core.数字
进入gdb然后使用bt命令
可以查看进程意外退出前函数调用的堆栈,内容为从上到下列出对应从里层到外层的函数调用历史。
假如进程意外退出不产生core文件,参考“ulimit -c core文件最大块大小”命令

20

嵌入式,没有环境,无法验证了。
PC上是没有问题的。
这个功能不行了就本人实现?
也不是很麻烦。根据长度插入补足字符就好了。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C++中字符流操作函数setfill()和setw()造成程序跑飞的问题