将 QList 拆分为块、指针或引用?
Posted
技术标签:
【中文标题】将 QList 拆分为块、指针或引用?【英文标题】:Splitting QList into chunks, pointers or references? 【发布时间】:2012-02-22 03:40:53 【问题描述】:我有这个应用程序,它要求我有一个包含 1
首先,我应该将 QList 声明为指针还是直接在堆栈上? QList 中的对象非常小,是 QFileInfo 的包装器。但是我该怎么做呢?
-
堆栈上的对象列表?
指向堆上对象的指针列表(在堆栈上)?
一个..
QList<FileInfoWrapper>*
首先,如果我选择了解决方案 2,我的堆是否会变得一团糟,因为我只是在整个地方分配了一小部分数据?我不想要那个。 其次,如果我选择第三种解决方案,当我访问各个对象时,它在内存中的外观如何?我可以创建指向它们的指针吗(它们毕竟在堆上)?
然后我们来谈谈我的另一个问题。该列表将像晚餐的叉子一样过去,在某些时候我想创建不包含任何数据的子列表,仅引用/指向列表中的某些对象(例如对象 0 到 250) .然后,我会将这些列表放入不同的线程中,这些线程必须具有对象的引用才能编辑它们(阅读:不是硬拷贝)。
另外,当您创建这样的列表时,有人可以准确解释堆上发生的情况:
QList<FileInfoWrapper>* list = new QList<FileInfoWrapper>();
会不会像在 c 中那样创建一个指向该对象所在偏移量的指针?
*(list + sizeof(FileInfoWrapper) * 10)
【问题讨论】:
或者我应该只将 2 个索引传递给不同的线程,然后在列表中循环从 start_index 到 end_index? 【参考方案1】:QList
是一个容器类……这意味着它会为您管理内存,因此您不必担心。它的底层数据结构是variant of a deque with some special modifications,因此您对列表索引的理解是不正确的。但无论哪种方式,这些都是由接口抽象出来的细节,您无需担心它们。您只需使用给定的类方法(如operator[]
或at()
)来获取对给定索引处对象的引用,并使用其他函数(如push_back()
或insert()
)将对象复制到容器中。因此,您可以简单地在堆栈上创建一个 QList
实例(只要它在需要时不会超出范围),然后将对象复制到其中。底层数据结构将正确分配动态存储对象所需的内存,并且在销毁QList
对象时,它将释放用于存储它“拥有”的对象的内存。
想想QList
,就像你想像std::vector
或std::list
这样的STL容器......再次,QList
的底层数据结构与这些STL容器不同,但重点是您可以像分配任何其他类一样在堆栈上分配数据结构,它包含所有私有数据成员和管理堆内存所需的信息。通过调用new
在堆上分配QList
在这方面不会为您带来任何好处......数据结构中已经有指针等,为您分配和管理所包含对象的内存.
最后,不要担心数据碎片。一个好的容器类的重点是正确分配内存以避免内存碎片问题,因为分配和重新分配内存过于频繁。此外,分配内存需要时间,所以如果一个容器类需要不断地调用new
,那真的会损害它的性能。虽然在每次插入时分配内存可能是基于节点的容器(如链表和树)的必要条件,但哈希表、动态数组和其他块类型数据结构在利用它们分配的内存方面更有效,以最小化这些分配调用。
【讨论】:
我可能只是非常疲倦,但我不确定您是否回答了我的第二个问题,即我应该如何将原始列表的块作为参考传递给不同的线程。我想做 QListRef(list.at(start), list.at(end)) 然后把它作为一个列表传递,所以我可以很容易地用“foreach”来完成它。 是的,我不明白您为什么不能这样做...要记住的是,如果您打算在将数据结构传递给线程(即添加更多对象),然后注意使对象的位置无效(即,底层内存重新分配可能会将存储对象的内容移动到其他地方,然后引用这些对象的线程什么都不引用)。如果您需要在添加或减去对象时不会改变的数据结构,您可能需要查看QLinkedList
。
等等什么?我的计划是将它作为对类的引用传递,然后使用 QList::at() 来处理其中一个对象。您的意思是,如果我在使用该引用的同时在列表中添加一个对象,我可能会遇到问题?
是的。这是一个单独的问题,但一些数据容器保证当一个线程将对象添加到容器时,它不会为容器中的任何其他对象重新定位内存。我不确定 QList 是否做出这种保证。虽然 QLinkedList 可以保证。以上是关于将 QList 拆分为块、指针或引用?的主要内容,如果未能解决你的问题,请参考以下文章