记一次C/C++字符串传输乱码的问题

众所周知,字符串并不是C语言里面的一种基本类型,因此字符串通常以char数组储存。通常情况下,我们通过参数传输字符串,是基本上没有问题的,除了以下两种情况:

  • char*变量超出作用域
  • 字符集不兼容

第二种一般很好解决,我们来讨论第一种情况,这种情况更复杂。首先,我们要了解,高级编程语言一个重要的特性就是堆栈,在C/C++中,堆内存是动态分配的,栈内存是静态分配的。一般而言,我们定义一个数组,就使用到栈内存,而栈内存的开辟和回收完全由作用域决定。全局变量的内存在程序开始运行时开辟,程序结束后回收;局部变量的内存在进去局部变量作用域时开辟,退出作用域后回收。但是,函数间传递字符串时,使用的是字符串数组的头指针,也就是说,如果在使用指针时,内存已经被回收,则导致使用了野指针,那么自然就会乱码。

一般使用子线程+PostMessage非常容易导致这个问题。众所周知,每个线程基本上就是在“异步”执行一个函数,而每个函数内的压栈就是在定义局部变量的时候发生的,出栈就是在函数结束后发生的。因为这个函数它是异步执行的,如果在子线程中通过PostMessage发送消息给主线程,主线程未必能及时处理,导致想要读取字符串的时候,子线程已经把栈内存释放了,进而导致乱码。

此外,如果你使用MFC中的CString类,还有一个小坑。CString为了节省内存,内部仅仅引用了堆内存,并且浅拷贝实际上只是把内部指针复制了过去。这就导致原来的对象释放后,这块内存也跟着回收了。解决方法也挺简单,就是使用一个独立的全局变量/成员变量来储存字符串,并将这个变量传给消息(不能在消息使用前覆盖掉,不然原来的内存就会被释放点,一样乱码)。

发表评论