Qt QVarLengthArray из QString Internals

0

Какова внутренняя структура данных QVarLengthArray?

Например, если у меня есть:

QVarLengthArray<QString> anArray;

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

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

Легко ли предварительно вычислить & anArray [1], данный & anArray?

Я просматривал исходный код QVarLengthArray, пытаясь понять, как QVarLengthArray хранит массив QStrings в памяти. Насколько мне нравится Qt, одна вещь, которая особенно болезненна для меня, - это ее непрозрачная основа указателя. (Вспомогательные функции в помощи отладчика в некоторых случаях, но когда вы действительно пытаетесь вникнуть во внутренние элементы, непрозрачные указатели скрывают большую информацию, которая в противном случае была бы доступна в отладчике.)

Я нашел пару статей "Qt Internals" на codeproject.com и в других местах, но никто не помог.

В общем, было бы здорово иметь возможность заглянуть в реальные структуры данных за непрозрачными указателями, но для непосредственной необходимости было бы прекрасно понять, есть ли хороший способ предсказать начальный адрес каждого элемента в QVarLengthArray из MyClass, который содержит указатели, QStrings и целые числа.

(Имея эту информацию, вы сможете упростить собственную сериализацию. Я понимаю риски повторного использования и готов принять эти риски для этого эксперимента.)

  • 0
    Так какой у тебя вопрос ...?
  • 0
    Основной вопрос заключается в том, какова внутренняя структура данных QVarLengthArray <MyClass>, где MyClass содержит QStrings.
Показать ещё 3 комментария
Теги:
arrays
qt

1 ответ

3
Лучший ответ

Посмотрите под "частным" разделом заголовков классов, чтобы найти переменные-члены - они расскажут вам о структуре класса. Здесь ссылка на первый член QVarLengthArray: http://code.woboq.org/qt5/qtbase/src/corelib/tools/qvarlengtharray.h.html#QVarLengthArray::a

В Qt 5 QVarLengthArray начинается с 2 ints, за которым следует указатель на первый элемент в массиве, за которым следует объединение, которое содержит собственно массив, предварительно выделенный в стеке.

Если размер вашего массива меньше или равен предварительно распределенной емкости, то &(array[1]) является просто фиксированным числом байтов после &anArray. Однако, если ваш массив будет больше, чем предварительно распределенная емкость, тогда QVarLengthArray вместо этого переключится на кучу. Когда это произойдет, больше нет отношения между &(array[1]) и &anArray.

Если у вас есть &anArray, надежный способ найти &(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 обещает source- и двоичную совместимость между малыми выпусками. Структура QVarLengthArray гарантированно останется неизменной до Qt 6, по крайней мере.

В общем, было бы здорово иметь возможность заглянуть в реальные структуры данных за непрозрачными указателями

Я считаю, что Woboq Code Browser очень полезен для этого - исходный код становится интерактивной сетью гиперссылок, и вы можете искать любой класс в библиотеке. Просто загляните в заголовок класса, чтобы найти непрозрачный указатель, и нажмите на него.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню