[英]How to free QByteArray created with fromRawData()
该文档指出以下内容 :
QByteArray不拥有数据所有权,因此,即使最后一个引用数据的QByteArray被销毁,QByteArray析构函数也不会删除原始数据。
考虑到这一点,如何释放以这种方式创建的QByteArray
?
从概念上讲-我猜想通过data()
或constData()
在指针上调用free()
,但我真的不确定...这是说明用例的代码示例:
void doTest() {
QByteArray qba = partOne();
partTwo(qba);
finished(qba);
}
QByteArray partOne() {
char *dataPtr = (char *)malloc(64);
//do some stuff to dataPtr
QByteArray qba = QByteArray::fromRawData(dataPtr, 64);
//do some stuff to qba
return qba;
}
void partTwo(QByteArray qba) {
//do more stuff to qba
}
void finished(QByteArray qba) {
//this?
free((void *)qba.constData());
}
如何释放以这种方式创建的
QByteArray
?
很简单-事实并非如此。 字节数组不拥有数据的所有权,因此您不会从字节数组中“释放”它。
如果有必要释放数据,则该责任应落在分配数据的代码上。 完成字节数组的操作后,不再有对其的引用。
数据可能是“可释放的”,也可能不是“可释放的”,因此,您不应尝试从字节数组中释放它。 无论采用何种机制分配数据,都应处理其释放。
memory allocation
byte array construction
byte array usage
byte array destruciton
memory deallocation
编辑:请记住,在您进行阅读或编写时,使用COW在“执行任务”和“执行任务”之间有很大的区别,因为在您编写时,COW就会启动,基础数据将被复制,并且更改将应用于它,而不是原始数据。 自然,只有在一个以上的字节数组实例隐式共享数据时才会发生这种情况,例如在partTwo()
。 如果您不希望这种情况发生,请通过引用而不是副本传递。 显然,如果启动了COW,则从data()
释放内存将是一个问题,因为您将释放由字节数组分配的新内存,而原始分配将变成内存泄漏。 因此,以下解决方案针对这种可能性。
void doTest() {
char *dataPtr = (char *)malloc(64);
//do some stuff to dataPtr
{
QByteArray qba = partOne(dataPtr);
partTwo(qba);
} // qba dies here
free(dataPtr);
}
QByteArray partOne(char *dataPtr) {
QByteArray qba = QByteArray::fromRawData(dataPtr, 64);
//do some stuff to qba
return qba;
}
void partTwo(QByteArray qba) {
//do more stuff to qba
}
完全不需要您手动管理内存:
QByteArray partOne() {
QByteArray qba(64, Qt::Uninitialized);
auto dataPtr = qba();
// use dataPtr
// do some stuff to qba
return qba;
}
fromRawData
没有所有权,因此应该由拥有您需要释放的数据的对象释放内存。
从概念上讲-我猜想通过.data()或.constData()在指针上调用free(),但是我真的不确定...
这是不正确的,因为您不能保证QByteArray
不拥有数据。 例如,如果您修改QByteArray
的内容,则将创建深层副本,并且该副本将由QByteArray
析构函数释放:
后续尝试修改返回的QByteArray的内容或由此产生的任何副本,将导致它在进行修改之前创建数据数组的深层副本。 这样可以确保原始数据数组本身不会被QByteArray修改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.