【问题标题】:Can't use big size QByteArray as QString不能使用大尺寸 QByteArray 作为 QString
【发布时间】:2017-11-17 20:44:22
【问题描述】:

我有很大的char* 对象。当我将此数组写入文件时,此文件的大小为 63.7 MB。我像这样从这个对象收到QByteArray 对象

QByteArray outputDataByteArray(outputData, outputSize);

如果我尝试将此对象发送为QString 参数,我会收到

传递给 C 运行时函数的参数无效。

在调试时我注意到它在以这个数组作为输入参数调用函数后崩溃,但没有出现在这个函数中。

我试过这样的

outputDataByteArray.append("\0");

根据文档信息,

警告:使用fromRawData() 创建的字节数组不是以空值结尾的,除非原始数据在位置大小处包含 0 字符。虽然这对于QDataStreamindexOf() 之类的函数无关紧要,但将字节数组传递给一个接受const char * 的函数,该函数应该是'\0'-terminated。

但这对我没有帮助。

在小尺寸数据上一切正常。

版本:

这是我收到的一些函数 QBytearray (一切正常):

uncompress(const QByteArray &inputByteArray, bool *ok)
{
if (ok != NULL)
    *ok = false;

const char *inputData = inputByteArray.data();

char *outputData = NULL;
qint64 outputSize   = 0;

for (int i = 0; i < CHUNK_COUNT_MAX; i++)
{
    const int outputSizeMax = CHUNKSIZE * (i + 1);
    outputData = new char[outputSizeMax];


    outputSize = LZ4_decompress_safe_withPrefix64k(inputData, outputData, inputByteArray.length(), outputSizeMax);

    if (outputSize < 0)
    {
        delete [] outputData;
        outputData = NULL;
    }
    else
    {
        break;
    }
}

if (outputData == NULL)
    return QByteArray();

QFile file("C:/Users/HOME/file.txt");
if(file.open(QIODevice::WriteOnly))
{
    file.write(outputData, outputSize);
}
file.close();

QByteArray outputDataByteArray(outputData, outputSize);

outputDataByteArray.append("\0");

delete [] outputData;

if (ok != NULL)
    *ok = true;

return outputDataByteArray;

}

但是,如果我尝试用这个数组作为参数调用另一个函数:

parse(outputDataByteArray, ok);

我收到了我上面写的内容。

补充: 它没有出现在这个函数中,而是我发送 QByteArray 作为参数的函数的定义:

parse(const QString &json, bool &success)
{
    success = true;
    if(!json.isNull() || !json.isEmpty())
    {
            QString data = json;

            int index = 0;


            QVariant value = Json::parseValue(data, index, success);


            return value;
    }
    else
    {
        return QVariant();
    }
}

【问题讨论】:

  • 请在您的问题中发布您的代码。
  • 我编辑了我的问题
  • LZ4_decompress_safe_withPrefix64k 的签名是什么?我猜但是......如果它是一个“C”函数并且应该分配给outputData,那么第二个参数不应该是&amp;outputData吗?
  • documentation 建议由调用者为outputData 分配内存在调用LZ4_decompress_safe_withPrefix64k 之前
  • 对不起,我是这个网站的新手。我编辑了我的问题,我正在为输出对象分配内存

标签: c++ qt


【解决方案1】:

你打电话给LZ4_decompress_safe_withPrefix64k

char *outputData = NULL;

而且,这个函数的定义是这样的:

int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize)
{
    return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
}

而且,LZ4_decompress_generic 的定义没有任何用于输出缓冲区的分配代码。请参阅definitionLZ4_decompress_generic

它只是在line # 1129中进行类型转换:

BYTE* op = (BYTE*) dest;

并且,它在整个函数的定义中被进一步使用,例如memcpyLZ4_wildCopyLZ4_copy8

因此,输出缓冲区指针指向的内存无效。您需要在将其传递给函数之前分配其内存。除此之外,您还需要在将指针传递给其他函数之前对其进行验证。您可以使用assertsif 检查来验证这一点。

希望这会有所帮助。

【讨论】:

  • 对不起,我是这个网站的新手。我编辑了我的问题,我正在为输出对象分配内存
  • @Leto:您需要隔离几件事来测试您的场景。首先,只需将该函数调用注释到库函数,然后观察其他代码的行为。如果没有问题,那么您将确定所有代码都工作正常。根据我的观察,LZ4_decompress_generic (grass.osgeo.org/programming7/lz4_8c_source.html#l01110) 不会附加任何类型的空字符来使其成为 C 风格的字符串。您需要在从中创建 QByteArray 之前对其进行验证。从您的代码来看,inputByteArray 的初始状态并不明显。
  • @Leto:您尝试过使用断点进行调试吗?有什么发现吗?你的内存大小是多少?你的操作系统?
  • RAM 8Gb OS Windows 7。问题只存在于大数据上。迷惑这一刻。在对大数据进行调试后,我注意到 outputData 是可读的,因为我将它写入文件并在那里检查。我收到此消息“传递给 C 运行时函数的参数无效”,然后才以输出数据作为参数调用另一个函数,但它不会进入该函数。从字节数组转换为字符串似乎有问题
  • @Leto: 你能在输入数据之前尝试reserve()QByteArray 吗?过去我也遇到过类似的问题,使用前保留内存解决了这个问题。
猜你喜欢
  • 2012-12-17
  • 1970-01-01
  • 2012-07-02
  • 2017-08-31
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多