如何释放使用 fromRawData() 创建的 QByteArray

dav*_*mer 2 c++ qt memory-management

该文档声明如下

QByteArray 不获取数据的所有权,因此 QByteArray 析构函数永远不会删除原始数据,即使最后一个引用数据的 QByteArray 被销毁。

考虑到这一点,如何QByteArray以这种方式释放受造物呢?

从概念上讲 - 我猜想通过orfree()调用指针,但我真的不确定......这是一个说明用例的代码示例:data()constData()

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());
}
Run Code Online (Sandbox Code Playgroud)

dte*_*ech 5

如何释放QByteArray以这种方式创建的东西?

很简单——没有人知道。字节数组不拥有数据的所有权,因此您不能从字节数组中“释放它”。

如果有必要释放数据,则该责任应由分配数据的代码承担。完成字节数组后,不再有对其的引用。

数据可能是也可能不是“可释放的”,因此您不应尝试从字节数组中释放它。无论分配数据的机制是什么,都应该处理其释放。

memory allocation
    byte array construction
        byte array usage  
    byte array destruciton
memory deallocation
Run Code Online (Sandbox Code Playgroud)

编辑:请记住,对于COW,在您阅读或写作时,“do stuff to”和“do stuff with”之间存在很大差异,因为当您写入时,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
}
Run Code Online (Sandbox Code Playgroud)