vector是std库提供的类似于数组的容器,在使用C语言数组的时候会遇到限制,数组大小不能动态扩展。
vector就是应对数组限制的一种支持动态增长容器。
首先看下面的实例
#include <vector>
int main(int argc ,char **argv)
{
std::vector<int> vector;
vector.push_back(1);
vector.push_back(2);
vector.push_back(3);
return 0;
}
(gdb) info locals
vector = {<std::_Vector_base<int, std::allocator<int> >> = {
_M_impl = {<std::allocator<int>> = {<__gnu_cxx::new_allocator<int>> = {<No data fields>}, <No data fields>}, _M_start = 0x46ca318,
_M_finish = 0x46ca320, _M_end_of_storage = 0x46ca320}}, <No data fields>}
从gdb中可以看到vector主要由4个变量组成,一个是内存分配器,另外3个是变量地址。
从我个人的理解,vector可以看出一个栈结构,_M_start是栈基,_M_end_of_storage是栈顶, _M_finish可以看成
vector中的结束位游标。
打印内存可以看到,在这段类似栈结构的内存当中。连续保存了我们压栈的数据。
0x4ef08a8: 0x00000001 0x00000002 0x00000003 0x00000021
0x4ef08b8: 0x00000000 0x00000000 0x00000000 0x00000000
同时,由于vector是连续内存段,所以在使用迭起器的时候,需要注意迭起器失效的问题。
并且vector是非线程安全的接口,所以使用时也主要保护。
list是数据结构中的链表的实现,看如下实例
#include <list>
int main(int argc ,char **argv)
{
std::list<int> the_list;
the_list.push_back(1);
the_list.push_back(2);
the_list.push_back(3);
the_list.push_back(4);
return 0;
}
(gdb) info locals
the_list = {<std::_List_base<int, std::allocator<int> >> = {
_M_impl = {<std::allocator<std::_List_node<int> >> = {<__gnu_cxx::new_allocator<std::_List_node<int> >> = {<No data fields>}, <No data fields>},
_M_node = {_M_next = 0x4d939b8, _M_prev = 0x5056968}}}, <No data fields>}
可以看到上面节点数据中,保存了前一个节点和后一个节点的内存地址。
打印前后内存地址可以得到当前节点的第三位是压入的data数据。
(gdb) x /8xw 0x4f670e8
0x4f670e8: 0x04f31e20 0x3c1d2da0 0x00000001 0x00000059
0x4f670f8: 0x01139cf0 0x04f683e0 0x00000005 0x04f68938
(gdb) x /8xw 0x4f8a408
0x4f8a408: 0x3c1d2da0 0x04f96c40 0x00000004 0x00000059
0x4f8a418: 0x00000000 0x00000030 0x04f89d30 0x04f8a4c8
(gdb) x /8xw 0x04f96c40
0x4f96c40: 0x04f8a408 0x04f31e20 0x00000003 0x00000029
0x4f96c50: 0x0000000a 0x0000000a 0x00000000 0x7473696c
(gdb) x /8xw 0x04f31e20
0x4f31e20: 0x04f96c40 0x04f670e8 0x00000002 0x00000011
0x4f31e30: 0x04f30048 0x04f11e50 0x00000010 0x00000019
并且最后一个节点指向了第一个数据,形成闭环。
list容器和vector一样,是非线程安全库,多线程使用时请注意数据同步
vector就是应对数组限制的一种支持动态增长容器。
首先看下面的实例
#include <vector>
int main(int argc ,char **argv)
{
std::vector<int> vector;
vector.push_back(1);
vector.push_back(2);
vector.push_back(3);
return 0;
}
(gdb) info locals
vector = {<std::_Vector_base<int, std::allocator<int> >> = {
_M_impl = {<std::allocator<int>> = {<__gnu_cxx::new_allocator<int>> = {<No data fields>}, <No data fields>}, _M_start = 0x46ca318,
_M_finish = 0x46ca320, _M_end_of_storage = 0x46ca320}}, <No data fields>}
从gdb中可以看到vector主要由4个变量组成,一个是内存分配器,另外3个是变量地址。
从我个人的理解,vector可以看出一个栈结构,_M_start是栈基,_M_end_of_storage是栈顶, _M_finish可以看成
vector中的结束位游标。
打印内存可以看到,在这段类似栈结构的内存当中。连续保存了我们压栈的数据。
0x4ef08a8: 0x00000001 0x00000002 0x00000003 0x00000021
0x4ef08b8: 0x00000000 0x00000000 0x00000000 0x00000000
同时,由于vector是连续内存段,所以在使用迭起器的时候,需要注意迭起器失效的问题。
并且vector是非线程安全的接口,所以使用时也主要保护。
list是数据结构中的链表的实现,看如下实例
#include <list>
int main(int argc ,char **argv)
{
std::list<int> the_list;
the_list.push_back(1);
the_list.push_back(2);
the_list.push_back(3);
the_list.push_back(4);
return 0;
}
(gdb) info locals
the_list = {<std::_List_base<int, std::allocator<int> >> = {
_M_impl = {<std::allocator<std::_List_node<int> >> = {<__gnu_cxx::new_allocator<std::_List_node<int> >> = {<No data fields>}, <No data fields>},
_M_node = {_M_next = 0x4d939b8, _M_prev = 0x5056968}}}, <No data fields>}
可以看到上面节点数据中,保存了前一个节点和后一个节点的内存地址。
打印前后内存地址可以得到当前节点的第三位是压入的data数据。
(gdb) x /8xw 0x4f670e8
0x4f670e8: 0x04f31e20 0x3c1d2da0 0x00000001 0x00000059
0x4f670f8: 0x01139cf0 0x04f683e0 0x00000005 0x04f68938
(gdb) x /8xw 0x4f8a408
0x4f8a408: 0x3c1d2da0 0x04f96c40 0x00000004 0x00000059
0x4f8a418: 0x00000000 0x00000030 0x04f89d30 0x04f8a4c8
(gdb) x /8xw 0x04f96c40
0x4f96c40: 0x04f8a408 0x04f31e20 0x00000003 0x00000029
0x4f96c50: 0x0000000a 0x0000000a 0x00000000 0x7473696c
(gdb) x /8xw 0x04f31e20
0x4f31e20: 0x04f96c40 0x04f670e8 0x00000002 0x00000011
0x4f31e30: 0x04f30048 0x04f11e50 0x00000010 0x00000019
并且最后一个节点指向了第一个数据,形成闭环。
list容器和vector一样,是非线程安全库,多线程使用时请注意数据同步