4_02_GLib库入门与实践_字符串块

简介

字符串块可用来存储多个字符串。字符串块有一个特点,当以const方式插入字符串时,若之前已经存在该字符串,则后插入的字符串不会开辟新的内存空间,只会指向之前的字符串,其实现原理为GStringChunk内部维护了一个hash表,当后插入的字符串为const方式插入,会从hash表中查找该字符串是否存在,若已存在,则不会重复插入。

数据结构

typedef struct _GStringChunk GStringChunk;

字符串块是一个不透明的数据结构,我们可以整体使用它,但无法单独访问其结构体成员。

函数列表

GStringChunk * 	g_string_chunk_new ()
gchar * 	g_string_chunk_insert ()
gchar * 	g_string_chunk_insert_const ()
gchar * 	g_string_chunk_insert_len ()
void 	g_string_chunk_clear ()
void 	g_string_chunk_free ()

函数功能分类

// 申请字符串块,如果某个字节比较大,则内存会自动扩展,不再是size,尚不明白size是单个字符串的长度还是总trunk的长度
GStringChunk *
g_string_chunk_new (gsize size);

// 向chunk插入一个字符串,插入的字符串占用新的内存,与g_string_chunk_insert_const不同,本接口不会查重,并且用本接口插入的字符串,用_insert_const函数也不会查出重复来。
gchar *
g_string_chunk_insert (GStringChunk *chunk,
                       const gchar *string);

// 与insert类似,但会查重,重复的字符串不会作为新内存插入,但可能会出现多个指针指向同一个内存字符串的情况。
gchar *
g_string_chunk_insert_const (GStringChunk *chunk,
                             const gchar *string);

// 当string有非结尾空字节时,此len保证拷贝的完整性
gchar *
g_string_chunk_insert_len (GStringChunk *chunk,
                           const gchar *string,
                           gssize len);

// 字符串块清空,清空之后就不能再安全地访问了
void
g_string_chunk_clear (GStringChunk *chunk);

// 字符串块释放,与new对应,不能单独对字符串进行释放,所有的字符串必须调用本接口一起释放
void
g_string_chunk_free (GStringChunk *chunk);

函数功能说明及综合演示

综合演示

代码演示:
源码见glib_examples\glib_gstringchunk\glib_gstringchunk_basic

#include <glib.h>

#define SIZE 5

struct _GStringChunk
{
  GHashTable *const_table;
  GSList     *storage_list;
  gsize       storage_next;
  gsize       this_size;
  gsize       default_size;
};

static void
test_string_chunks (void)
{
    int i = 0;
    GStringChunk *sc = NULL;
    gchar *str[SIZE];

    g_printf("\n");

    sc = g_string_chunk_new (4096);
    str[0] = g_string_chunk_insert(sc, "AA");
    str[1] = g_string_chunk_insert_const(sc, "AA");
    str[2] = g_string_chunk_insert_const(sc, "BBBB");
    str[3] = g_string_chunk_insert_const(sc, "BBBB");
    str[4] = g_string_chunk_insert(sc, "CCC");

    for(i=0;i<SIZE;i++) {
        g_print("str[%d]: %s \n", i, str[i]);
    }

    g_print("chunk this_size=%d, storage_next=%d \n", (gint)sc->this_size, (gint)sc->storage_next);

    g_string_chunk_clear(sc);
    g_string_chunk_free(sc);    
}

int main (int argc, char *argv[])
{
  g_test_init(&argc, &argv, NULL);

  g_test_add_func("/string/test_string_chunks", test_string_chunks);

  return g_test_run();
}

运行结果:

/string/test_string_chunks: 
str[0]: AA 
str[1]: AA 
str[2]: BBBB 
str[3]: BBBB 
str[4]: CCC 
chunk this_size=4096, storage_next=15 
OK

运行结果分析:
g_string_chunk_insert_const插入相同字符串时是否会占用额外内存空间?
在解答这一疑问时,需要用到_GStringChunk结构体,其中的storage_next的值就是当前已经存的字节数,由于此结构体不透明,需要在测试例中自己定义了_GStringChunk结构体。

sc->storage_next值为15,其计算方法如下:
str[0] = g_string_chunk_insert(sc, "AA"); // 3个字节
str[1] = g_string_chunk_insert_const(sc, "AA"); // insert插入的无法查到,因此还是需要占3个字节
str[2] = g_string_chunk_insert_const(sc, "BBBB"); // 5个字节
str[3] = g_string_chunk_insert_const(sc, "BBBB"); // 由于之前是const方式插入,此时发现重复,不再开辟内存,不占字节
str[4] = g_string_chunk_insert(sc, "CCC"); // 4个字节
因此3+3+5+4=15
可见,insert插入的,insert_const无法查到,insert_const多次插入同一个字符串,只会占用一份内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值