【问题标题】:Qt QVarLengthArray of QString InternalsQString 内部的 Qt QVarLengthArray
【发布时间】:2014-09-18 01:35:18
【问题描述】:

QVarLengthArray 的内部数据结构是什么?

例如,如果我在哪里拥有:

QVarLengthArray<QString> anArray;

QString string1 = "whatever";
QString string2 = "something else";

anArray[0] = string1;
anArray[1] = string2;

在给定 &anArray 的情况下预先计算 &anArray[1] 容易吗?

我一直在浏览 QVarLengthArray 源代码,试图了解 QVarLengthArray 如何在内存中存储 QString 数组。尽管我很喜欢 Qt,但对我来说特别痛苦的一件事是它不透明的指针基础。 (调试器中的辅助函数在某些情况下会有所帮助,但当真正尝试深入研究内部时,不透明的指针会掩盖大量原本在调试器中可用的信息。)

我在 codeproject.com 和其他地方找到了几篇“Qt Internals”文章,但没有任何帮助。

一般来说,有一种方法可以窥探不透明指针背后的真实数据结构,但对于即时需要,了解是否有一种很好的方法来预测每个指针的起始地址会很好MyClass 的 QVarLengthArray 中的元素,其中包含指针、QStrings 和整数。

(拥有这些信息将有助于简化自定义序列化。我确实了解可重用性的风险,并且愿意为这个实验接受这些风险。)

【问题讨论】:

  • 那么你的问题是什么...?
  • 主要问题是 QVarLengthArray 的内部数据结构是什么,其中 MyClass 包含 QStrings。
  • 如果知道如何在调试器中查看 Qt 的不透明指针背后的真实数据结构(在我的例子中是 Creator 中的 gdb),那也很棒。
  • 我明白你的意思。我将编辑原始帖子以使问题更清楚。谢谢。
  • 好的,我对原始问题进行了编辑,我相信这会使问题更加清晰。

标签: c++ c arrays qt


【解决方案1】:

查看类头的“私有”部分以查找成员变量——这些将告诉您类结构。这是 QVarLengthArray 的第一个成员的链接:http://code.woboq.org/qt5/qtbase/src/corelib/tools/qvarlengtharray.h.html#QVarLengthArray::a

在 Qt 5 中,QVarLengthArray 以 2 个 int 开头,后跟指向数组中第一个元素的指针,然后是保存实际数组本身的并集,预先分配在堆栈上。

如果您的数组大小小于或等于预分配的容量,则&amp;(array[1]) 只是&amp;anArray 之后的固定字节数。但是,如果您的数组增长大于预分配的容量,则 QVarLengthArray 将改为切换到堆。发生这种情况时,&amp;(array[1])&amp;anArray 之间不再有任何关系。

如果您有&amp;anArray,找到&amp;(anArray[1]) 的可靠方法如下:

QString* anArray_0 = (&anArray)->begin(); // &(anArray[0])
QString* anArray_1 = anArray_0 + 1; // &(anArray[1])

或者,在不调用任何成员函数的情况下以低级方式执行此操作(假设没有填充):

// Use reinterpret_cast to enable 1-byte pointer arithmetic
char* outerPtr = reinterpret_cast<char*>(&anArray);

QString* anArray_0 = reinterpret_cast<QString*>( outerPtr + 2*sizeOf(int) ); // &(anArray[0])
QString* anArray_1 = anArray_0 + 1; // &(anArray[1])

(拥有这些信息将有助于简化自定义序列化。我确实了解可重用性的风险,并且愿意为这个实验接受这些风险。)

Qt 承诺跨次要版本的源代码和二进制兼容性。 QVarLengthArray 的结构保证至少在 Qt 6 之前保持不变。

一般来说,有一种方法可以窥探不透明指针背后的真实数据结构

我发现Woboq Code Browser 对此非常有用——源代码变成了一个超链接的交互式网络,您可以在库中搜索任何类。只需在类头中找到不透明指针,然后单击它。

【讨论】:

    猜你喜欢
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多