Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 确保QByteArray拥有其内存(QByteArray::fromRawData)_C++_Qt_Qbytearray - Fatal编程技术网

C++ 确保QByteArray拥有其内存(QByteArray::fromRawData)

C++ 确保QByteArray拥有其内存(QByteArray::fromRawData),c++,qt,qbytearray,C++,Qt,Qbytearray,假设我们有一个函数库 void store(const QByteArray& data); 此函数的任务是获取数据并将其存储起来。不幸的是,如果参数是使用QByteArray::fromRawData(ptr,size)创建的,那么这样做是不安全的,因为它及其所有副本都要求ptr保持有效 因此,store没有选项禁止其调用者传入这样的数组,将数据视为立体像上的常量字符*,或使用分离强制深度复制。所有这些都不令人满意,尤其是后者会影响性能,因为如果数据在传递到存储之前被复制,我们将进行

假设我们有一个函数库

void store(const QByteArray& data);
此函数的任务是获取
数据
并将其存储起来。不幸的是,如果参数是使用
QByteArray::fromRawData(ptr,size)
创建的,那么这样做是不安全的,因为它及其所有副本都要求
ptr
保持有效

因此,
store
没有选项禁止其调用者传入这样的数组,将
数据
视为立体像上的
常量字符*
,或使用
分离
强制深度复制。所有这些都不令人满意,尤其是后者会影响性能,因为如果
数据
在传递到
存储
之前被复制,我们将进行不必要的深度复制

QByteArray
有一个
private
函数
nulTerminated
,它的实现似乎正是我想要的:如果它不拥有内存,它会进行深度复制。如果它拥有内存,它只返回
*this

真的有两个问题吗

  • 使用
    公共
    设施是否有变通办法

  • Qt文档提到,
    ptr
    必须仅在返回值及其任何副本的生存期内处于活动状态。如果您说
    .right(.size())
    ,这似乎不是一个副本,因此Qt需要根据文档制作一个深度副本。但它真的这样做了吗

  • 查看源代码(例如),
    ba.right(ba.size())
    实际上是纯浅拷贝,几乎没有操作,所以这不是您的解决方案。而且在任何情况下,依赖没有文档支持的任何行为都有点不安全,在未来的Qt版本中可以在不通知的情况下进行更改

    也就是说,它是无文件记录的,但是公开的。它将对使用
    fromRawData()
    创建的数组执行深度复制,但不会对已经非共享的数据执行深度复制,我认为这不太可能改变。演示:

    QByteArray ba1 = QByteArray::fromRawData("foo", 4);
    QByteArray ba2("foo");
    qDebug() << (void*)ba1.constData() << (void*)ba2.constData();
    ba1.detach(); ba2.detach();
    qDebug() << (void*)ba1.constData() << (void*)ba2.constData();
    


    查看qbytearray.cpp文件中的源代码,我没有发现任何可以使用公共接口利用它的方法。因此,想做什么似乎是不可能的,而且
    detach()
    是最接近的,即使
    QByteArray::squeak()
    不分离原始数据。

    这听起来更像是一个概念问题,而不是技术问题

    store()
    试图取得绝对所有权,但在QByteArray上“取得所有权”在概念上没有多大意义。一个副本可能与另一个共享内存,也可能不共享内存,或者它可能是从原始数据创建的,因此在后台存在一个隐藏的所有权把戏,整个类都是为了向您隐藏这一点而设计的。整个隐式共享与现代显式所有权转移范式总体上不匹配,QByteArray通过提供原始数据工具使问题进一步复杂化


    如果可能的话,通过右值接受一个非隐式共享的容器,该容器对其内容拥有绝对所有权(例如std::string,它可以很容易地用QByteArray::toStdString()生成),强制调用方进行复制,这将是最好的选择。

    但据我所知,它还将深度复制
    QByteArray a(“hello”);QByteArray b=a;b、 分离()这是不需要的。所以我想我需要用私有访问黑客攻击它并调用nulTerminate函数。谢谢你的努力
    
    0x804b960 0x93ebfd8
    0x93d2170 0x93ebfd8