我试图理解std::list
数据结构如何分配内存。我做了一个小测试程序
#include <cstdio>
#include <vector>
#include <iostream>
#include <string>
#include <list>
class MyClass
{
public:
MyClass();
~MyClass(){}
private:
std::list<unsigned char> numlist;
};
MyClass::MyClass()
{
numlist.push_back(1);
}
int main()
{
MyClass c; // instantiate
}
我在valgrind
中运行了上面的代码片段$valgrind --leak-check=full ./indepth
==32330== HEAP SUMMARY:
==32330== in use at exit: 0 bytes in 0 blocks
==32330== total heap usage: 1 allocs, 1 frees, 24 bytes allocated
请帮助我理解为什么在这里分配了24个字节。
答案 0 :(得分:2)
在不了解特定编译器及其选项的情况下,很难给出明确的答案。但是对push_back
的调用将为它创建的列表元素分配一个节点,该节点将有两个指针(一个用于下一个节点,一个用于前一个节点),一个int
包含储存的价值。要获取有关这些部件尺寸的详细信息,请运行以下程序:
#include <iostream>
int main() {
std::cout << sizeof(int*) << ", " << sizeof(unsigned char) << '\n';
return 0;
}
这将告诉你指针有多大以及int
有多大。
答案 1 :(得分:2)
std::list
中每个元素的确切大小取决于STL实现,但通常它实现为双链表,这意味着每个节点(代表元素)需要至少3个数据成员(上一个节点,下一个节点,以实现双链接列表和数据)。
在gcc实现中,文件 std_list.h 类_List_node
包含此节点的定义。 2个指针(32位中的2 * 4个字节或64位中的2 * 8个字节)加上sizeof(数据)。
除此之外,列表可能必须维护一些其他内部信息,例如大小(因为C ++ 11是由std::list::size()
O(1)的标准规定的
注意:
STL实施 = 标准库实现(编译器附带的C ++标准库的实现或配置为由编译器使用)
还有其他STL实现,如 STLPort 等......这些细节与实现有关。唯一可以确定的方法是查看特定版本STL实现的代码,确切的大小可能随时改变。
答案 2 :(得分:1)
请帮助我理解为什么在这里分配了24个字节。
此类详细信息是特定于实现的,因此最终答案取决于编译器和标准库的源代码或文档。在另一个实现中,内存使用可能会有很大不同。
但是,可以基于双重链表的简单实现进行有根据的猜测:在编译时通常无法知道节点数,因此它们可能需要动态分配。节点应具有指向下一个和上一个节点的指针以及存储的数据。这是1 string text = " ";
int StartLocation = 0;
int EndLocation = 0;
//I roughly know the starting location
//starting at I=2248 so I don't
//through entire document
for (int i = 2248; i < 2700; i++)
{
text = document.Paragraphs[i + 1].Range.Text.ToString();
if (text.Contains("firstWordImSearchingFor"))
{
StartLocation = i;
}
if (text.Contains("lastWordImSearchingFor"))
{
EndLocation = i;
}
}
//delete everything between those paragraph locations
//(not working correctly/ skips lines)
for(int i = StartLocation; i<EndLocation-1i++)
{
document.Paragraphs[i+1].Range.Delete();
}
和2指针。在特定的体系结构中,很可能指针的大小恰好是8个字节。 int
通常也适合8个字节,但即使它更小,也必须将节点填充到最接近的8字节边界以满足指针的对齐要求。对于这个虚构的平凡实现,这使得8 * 3 = 24个字节。标准库使用的实际实现可能类似。
答案 3 :(得分:0)
容器std::list
是一个链表,因此它分配的节点不仅包含您的元素,还包含两个指针:一个指向下一个节点的指针和一个指向前一个节点的指针。
如果您想要更高效的内存容器,请考虑使用std::vector
并使用std::vector::reserve
函数预分配内存。