glibc教程(Glib学习笔记(4) Innost的专栏 博客频道 CSDN.NET)
四数据结构
这部分非常重要 。
4.1 内存片管理
memory slices是一个高效的分配和管理等尺寸的类 。
这个和普通的new/delete相比有什么特别之处?
似乎更高效 ,有分布式内存管理“之嫌“ 。建议替代g_malloc系列 。
没看出什么特别之处啊 ,暂时用malloc 。
包括一个过时的gmemchunk类 ,这里不叙述了 。
4.2 双/单向链表
GList是双向链表 。仔细看看和STL相比提供了哪些不同之处 。
lGList内部单元都是从slice allocator中分配得来的 ,所以应该很高效 。
l分配GList* p = NULL
l插入用,append,prepend,insert,insert_sorted
l删除:remove
l迭代:first,nth等
l遍历:foreach
l查找index(这个估计是GList特别提供的)index()
注意:GList没有一个单独的对象来表示整个队列集合 ,不像STL就用list来表示整个集合 。内部单元是单独的一个东西 。所以使用GList一定要注意了 ,GList本身就是单元 ,所以一定要维护GList链表的头单元 。
另外 ,GList是单元 ,内部有指针指向内存块 ,GList本身是可以从slice中分配得来的。所以free Glist的时候是将单元本身返回slice中 ,而内部的执行内存块需要自己去释放 。
它这个find函数很有特点 ,find的对比参数是单元中的data指针 。好像STL中的也是这样的哈。要是有个函数指针参数就好了 。这就得用到find_custom函数了
单向链表用GSList就行了 。
其他好像差不多,没有提到过操作函数的效率问题 ,因为不是泛型编程 ,所以没有哪个API是通用的 。
4.3 双端队列
双端队列用GQueue表示,这个和STL类似 。
GQueue有静态分配的 ,而上述的list没有 。这点真的很奇怪 。
看了GQueue的内部结构 ,发现里边是两个GList 。
有clear函数了 。这里有xxx_link函数 ,link的参数是一个GList 。前面的insert等是一个数据data ,内部会分配一个GList单元的 。
4.4 序列
序列实际是一个内部采用平衡树来实现的链表 。
看来就是一个set吧 ,内部是排序的 。
GSequence代表序列 ,需要用GSequenceIter来迭代 ,它这个begin和last位置是否和STL中的一致呢?last是最后一个的后边。begin是第一个的前边 ,看来就这个begin不一样 ,双方都是全开空间 。另外 ,不像STL中的迭代子 ,GSIter在整个操作过程中不会无效(除非删掉该元素) ,这一点确实比较不一样 。
怎么解引用GSIter?也是一个指针的指针吗?应该不是。
l获取begin等位置:g_seqx_get_begin_iter,end_iter
lappend,prepend等返回iter
l序列最重要的是find函数,这里叫search 。
l迭代前后 ,iter_next,iter_prev
l解引用iter ,用g_sequence_get/set等,set最好不要直接去设置 ,否则就不会排序了 。
有点麻烦 ,因为即使最简单的int类型都得提供一个比较函数 ,难道没有些默认的吗?
4.5 TrashStack
GTrashStack,垃圾栈?目的是什么?用于回收不用的内存块 。不知道有什么用 。一般要是内存块不用的话直接就free了 。
从提供的API来看 ,似乎就是一个保存free内存块的地方 ,只不过用stack结构来存储罢了 。
4.6 Hash表
GHashTable表实际非常有用 ,但是STL并没有提供对应的对象 。GLIB的hash结构需要自己提供hash函数 ,这个比较麻烦 ,有没有默认的hash函数呢?GLIB提供了字符串哈希函数 ,整型hash函数等 。极大方便使用了 。注意以下:
lGLIB的哈希并不copy一份key和value ,所以得自己保存 。这个确实也是 ,因为C中没有运算符重载之说 ,也没有拷贝构造函数 。
越来越感觉GLIB中API的封装与从并行开发中学到的API编写非常类似,到处是函数指针 。
GHashTableIter ,一般在栈上分配 ,然后用g_hash_table_iter_init来初始化并使用之。
在使用中如果修改了HASH表,将使得iter无效 。
4.7 String对象
1. GString
GString类似CString ,但使用上肯定不如对象封装的C++方便 。
GString内部数据指针由str指示。
2. GStringChunk
一个string的集合 ,难道类似CStringArray?当许多string需要操作的时候 ,用这个比g_strdup要方便 ,因为它不会频繁得去malloc内存 。
有几个函数需要特别注意:
linsert_const和insert ,这里内部好像会区分是怎么加入到chunk中的 ,而且搜索的时候会区分开来类型 。
4.8 Array
g_array_free这个函数比较让人思考 。如果free_segment为FALSE的话将返回内部element-data的指针 。难道内部是一整块内存吗?从GArray的结构来看好像确实是 。
1. GPtrArray
存放指针的array 。与上面的差不多 ,不过可以设置element_destroy_func 。
2. ByteArray
存放Byte的array 。
4.9 平衡二叉树
GTree提供平衡二叉树的功能 。这个其实就是搜索二叉树有key和value之分 。
对应STL中的map ,用得是红黑树 。
GTree提供遍历接口 ,GTraverseType ,和树完全一样 ,如中序 ,前序,后序 ,层级遍历 。
4.10 N序树
这个用得很少 ,GNode表示一个节点,没有单独的表示集合的数据结构。
不说了 ,关键还是看应用需要 。
4.11 Quarks
GQuark 。不知道这个怎么翻译 ,但实际作用就是将一个字符串与一个GQuark对象对应。姑且可以看做是某种意义上的String的hash 。
注意 ,这个不是一个集合 。GQuark应该是一个单元 ,这个单元的值由一个string计算得来 ,看来还有使用GQuark作为单元的集合 ,后续会用到 。
内部GQuark就是一个整数 。看API ,难道内部有一个巨大的集合来存储string ,这样可以避免同一个内容的string来产生一样的quark 。
看了下实现 ,果真里边有一个全局的HashTable
4.12 带关键值的数据列表Keyed Data List
GData提供了通过CQuark方式来快速访问的接口 。实际就是Hash操作 ,为啥会有这种需求?大概用在GObject这种大量使用字符串来表示key的地方 。
4.13 数据集Data Sets
用法很奇特 。目的比较明确 。
哪儿肯定有全局的东西在保存着 。dataset没有对应的数据结构 。
怎么用这个啊?难道每次都要先搞一个location出来吗?
非常奇特 。但好像很有用。
4.14 关系和元组 Relations and Tuples
GRelation/GTuples ,难道类似Erlang中的吗?
GRelation是一个表 ,里边的item是GTuples,每个GTuple含多个列(目前限2列) 。
有点像列表控件 。
4.15 Cache
Glib对Cache机制还进行了封装 ,难得.... ,具体设计上也用都了key/value,这个是必须的。
API使用有特点 ,如果插入的key不存在 ,则通过回调方式来创建value ,然后就返回这个value 。这个和我们以前想的先创建key和value ,然后再加进去的方法完全不一样 。
4.16 过时的内存分配
不再多说 。
五 Glib工具
glib-gettextize ,干嘛使的?国际化用的 ,参考gettextize 。用于系统的国际化和本地化 ,可以在编译程序的时候使用本国语言支持(NLS) ,可以使程序的输出使用用户设置的语言而不是英文 。
gtester:单元测试程序 。并将结果格式化输出成XML/HTML
gtester-report:格式化XML到HTML的工具 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!