前言
之前有一个项目,需要接收来自其他地方的数据进行处理,由于是char指针类型,而且数据长度不固定,因此琢磨将其转换为QByteArray类型进行处理,但是没想到居然还有坑存在。
问题复现
当时的整个处理流程如下,首先需要接收一堆char*指针类型的不定长数据,这里模拟函数如下:
void MainWindow::gen_data(char *buf,int max_len)
{
for(size_t i = 0;i < max_len ;i++)
{
buf[i] = i & 0xff;
}
}
然后将其转换为QByteArray类型数据;简单示意代码如下:
void MainWindow::char_to_bytes(QByteArray & bytes)
{
char *buf = new char[256];
gen_data(buf,256);
QByteArray arr = QByteArray::fromRawData(buf,256);
bytes = arr;
delete [] buf;
}
乍一看好像没什么问题,但是一调试发现,接收到的数据全是乱码。
于是进一步调试发现,在转换函数里面都是对的,退出此函数就不正常了,考虑到用到了动态内存分配,猜测可能数据在删除缓冲区时被标记为了脏数据。
仔细看了一下该函数,果然发现了问题,数据不会被拷贝,也就是说仅仅是一个指针指向*data缓冲区,难怪动态分配的内存一回收数据就有问题。
考虑到以前都是这么用的,也没有出现问题,没想到此次栽了个大坑。想了想以前的缓冲区要么是没回收,要么是回收前数据已经处理完成,难怪没出问题。
解决方法
既然知道问题所在,那解决起来就简单了,找了下Qt的帮助文档,终于找到了一个可以拷贝数据的函数,函数原型如下:
QByteArray &QByteArray::append(const char *str, qsizetype len)
解释如下:
修改代码如下,调试,问题已经解决。
void MainWindow::char_to_bytes(QByteArray & bytes)
{
char *buf = new char[256];
gen_data(buf,256);
// QByteArray arr = QByteArray::fromRawData(buf,256);
QByteArray arr;
arr.append(buf,256);
bytes = arr;
delete [] buf;
}
问题得到解决。
总结
不要盲目相信以前的经验,问题可能很简单,但是找起来是真的折磨人。
出问题多看手册,这问题在网上还真难找到案例。