crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Какой тип структуры данных у QVector, QList, QMap?
AXELman4ever
  опции профиля:
сообщение 22.9.2011, 23:16
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 31
Регистрация: 22.9.2011
Пользователь №: 2902

Спасибо сказали: 0 раз(а)




Репутация:   0  


Доброго времени суток. Перечитал множество информации касательно работы этих контейнеров, но так и не нашел ответ на вопрос "Так где же хранится то, что находится в контейнере?" - в стеке или куче?

К примеру, я имею:

QVector<int> vect_int;

и

QVector<QWidget *> vect_widget;

вызывая метод push_back() для обеих случаев, что происходит в памяти, что кладется в мой вектор, и где хранится то, что кладется в мой вектор? или другими словами - где вектор хранит ссылки на объекты или же сами объекты?

в контейнерах QList и QMap происходит тоже самое? (о том что такое QList, QMap, и о принципах их роботы мне известно)

Убедительная просьба - растолковать. Перекопал весь инет - нигде ничего об этом не упоминается.
Заранее благодарен.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Авварон
  опции профиля:
сообщение 22.9.2011, 23:34
Сообщение #2


Студент
*

Группа: Участник
Сообщений: 99
Регистрация: 26.4.2009
Пользователь №: 709

Спасибо сказали: 14 раз(а)




Репутация:   0  


Всегда в куче. Имея размер стека 2мб много данных не похранишь.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AXELman4ever
  опции профиля:
сообщение 22.9.2011, 23:53
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 31
Регистрация: 22.9.2011
Пользователь №: 2902

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Авварон @ 22.9.2011, 23:34) *
Всегда в куче. Имея размер стека 2мб много данных не похранишь.


Ок, а каким образом получается так, что объекты, хранящиеся в куче занимают места по порядку? Об этом заботится архитектура класса?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Vass
  опции профиля:
сообщение 23.9.2011, 1:28
Сообщение #4


Студент
*

Группа: Участник
Сообщений: 46
Регистрация: 17.3.2009
Из: Россия, Рыбинск
Пользователь №: 617

Спасибо сказали: 8 раз(а)




Репутация:   0  


Цитата(AXELman4ever @ 23.9.2011, 0:53) *
Ок, а каким образом получается так, что объекты, хранящиеся в куче занимают места по порядку? Об этом заботится архитектура класса?

Да, если вы откроете qvector.h/cpp

Вы увидите там приватный класс QVectorData

С такими методами:

 static QVectorData *malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init);
    static QVectorData *allocate(int size, int alignment);
    static QVectorData *reallocate(QVectorData *old, int newsize, int oldsize, int alignment);
    static void free(QVectorData *data, int alignment);


Если внимательно изучить код, то становится видно, что класс QVector выделяет на куче кусок памяти и в нем по порядку размещает элементы, соответсвенно если не хватает места вызывается reallocate ну и т.д.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 23.9.2011, 7:51
Сообщение #5


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


AXELman4ever, полагаю, что QVector устроен аналогично std::vector.

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

std::vector<int> vec(10,0); //контейнер на 10 элементов, инициализированных 0

int* pArray=&vec[0]; //указатель на начало массива
//vec.size()  - количество элементов в массиве


память, конечно же, выделяется на куче. Если вместо статических массивов всегда применять вектор, то можно забыть об уязвимости, связанной с переполнением буфера, так как в куче переполнение не испортит содержимое стека напрямую

когда меняем размер контейнера в бОльшую сторону, то контейнер смотрит, хватает ли ему уже выделенной заранее памяти (см.методы reserve , capacity) . Если хватает, то массив в памяти не меняет адрес, только увеличивается в размере (увеличивается соответствующая переменная в классе, хранящая текущую длину массива). Если памяти мало, то происходит переаллокация - выделяется новый блок памяти нужного размера, данные копируются, старый блок возвращается в кучу. Операция очень "тяжёлая" в плане быстродействия, поэтому всегда нужно планировать и контролировать возникновение переаллокаций всех алгоритмах, где производится очень много изменений размера массива. Заранее зарезервировать память можно через reserve. При переаллокации становятся невалидными все итераторы и указатели, связанные с данными в контейнере. При уменьшении размера вектора (а также при вызове метода clear или методов resize/assign с мЕньшим размером, чем size() ) переаллокации не происходит, освободившаяся часть памяти остаётся висеть "мёртвым грузом" (вернее - быть зарезервированной). Это часто удобно, когда содержимое вектора часто меняется, не превышая определённый размер массива.

У вектора есть особенность: при добавлении N элементов типа T, конструктор T() вызывется один раз, затем этот объект копируется во все элементы оператором = (он должен быть определён для T). Поэтому, если в конструкторе T() имеется, к примеру, некий статический счётчик экземпляров класса T , то этот счётчик будет считать некорректно (меньше, чем на самом деле). Деструкторы для каждого элемента вызываются исправно


QMap использует внутри себя узлы с указателями на соседние узлы, поэтому данные располагаются в памяти в общем случае непоследовательно или с разрывами между элементами. Но зато не бывает переаллокаций, как у вектора, а вставка в середину контейнера выполняется гораздо быстрее, чем в вектор

Сообщение отредактировал Алексей1153 - 23.9.2011, 18:37
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 23.9.2011, 8:01
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Алексей1153 @ 23.9.2011, 8:51) *
QList и QMap используют внутри себя узлы с указателями на соседние узлы, ...

Это не про QList. Связанный список в Qt это QLinkedList.
QList это скорее умный std::vector.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 23.9.2011, 9:44
Сообщение #7


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


BRE, я с ним не работал, если честно ) Ну а в чём его умность ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 23.9.2011, 10:23
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Алексей1153 @ 23.9.2011, 10:44) *
BRE, я с ним не работал, если честно ) Ну а в чём его умность ?

Он сам решает, в зависимости от типа данных, как их хранить. Если sizeof типа меньше или равен размеру указателя, то данные хранятся как в обычном std::vector, а если больше или тип не POD, то хранить указатели на данные.

Сообщение отредактировал BRE - 23.9.2011, 10:43
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 23.9.2011, 10:28
Сообщение #9


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


BRE, понятно ) Никогда не буду им пользоваться, зачем мне такая самодеятельность
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AXELman4ever
  опции профиля:
сообщение 23.9.2011, 12:30
Сообщение #10


Студент
*

Группа: Участник
Сообщений: 31
Регистрация: 22.9.2011
Пользователь №: 2902

Спасибо сказали: 0 раз(а)




Репутация:   0  


Премного благодарен всем отписавшимся здесь, в отдельности - Алексей1153. Просто, точно и доступно ;)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 23.11.2024, 1:06