Coder Social home page Coder Social logo

cstring's Introduction

cstring 库

C 语言没有原生的 string 类型,这使得 string 的管理非常麻烦。cstring 是一个简单的 string 库,它主要解决以下几个问题:

  • 对于短字符串(小于 32 字节),进行 string interning 。这可以在文本处理时节约不少内存。短 string 相当于 symbol 类型,对它做比较操作的代价可以减少到 O(1) 。
  • 对于临时字符串,如果长度不大(小于 128 字节),尽可能的放在 stack 上,避免动态内存分配。
  • 支持常量字符串,对于常量短字符串只做一次 string interning 操作。
  • 使用引用计数管理相同的字符串,减少字符串的拷贝。
  • 短字符串,常量字符串,以及引用次数非常多(大于 64K 次)的字符串可以不动态释放,简化生命期管理。
  • 惰性计算,以及缓存字符串的 hash 值,以方便实现 hashmap 。
  • 这个库是线程安全的。

cstring_buffer

不要直接定义 cstring_buffer 类型,而应该用 CSTRING_BUFFER(var) 声明,它相当于声明了一个名为 var 的 cstring_buffer 对象。

cstring_buffer 位于栈上,通常不需要回收。但是在函数结束时,应该使用 CSTRING_CLOSE(var) 关闭它。

新声明的 cstring_buffer 对象是一个空字符串,可以用下面两个 api 修改它。

cstring cstring_cat(cstring_buffer sb, const char * str);
cstring cstring_printf(cstring_buffer sb, const char * format, ...);

cstring

如果需要把字符串做参数传递,就应该使用 cstring 类型,而不是 cstring_buffer 类型。CSTRING(var) 可以把 var 这个 cstring_buffer 对象,转换为 cstring 类型。

但是,在对 cstring_buffer 对象做新的操作后,这个 cstring 可能无效。所以每次传递 cstring_buffer 内的值,最好都重新用 CSTRING 宏取一次。

函数调用的参数以及返回值,都应该使用 cstring 类型。如果 cstring 是由外部传入的,无法确定它的数据在栈上还是堆上,所以不能长期持有。如果需要把 cstring 保存在数据结构中,可以使用这对 API :

cstring cstring_grab(cstring s);
void cstring_release(cstring s);

把 cstring 转化为标准的 const char * ,只需要用 s->cstr 即可。

cstring 的比较操作以及 hash 操作都比 const char * 廉价,所以,请使用以下 API :

int cstring_equal(cstring a, cstring b);
uint32_t cstring_hash(cstring s);

literal

CSTRING_LITERAL(var, literal) 可以声明一个常量 cstring 。这里 literal 必须是一个 " 引起的字符串常量。

cstring's People

Contributors

cloudwu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cstring's Issues

在format超长字符串的时候,多次把va_list ap传入vsnprintf中可能会导致不确定的行为?

云风老师您好,我在仿造你的程序写自己的字符串类的时候,发现生成的字符串有错误,仔细分析原因,认为问题应该出在vsnprintf这个函数的调用处,根据manpage

The functions vprintf(), vfprintf(), vdprintf(), vsprintf(), vsnprintf() are equivalent to the functions printf(), fprintf(), dprintf(), sprintf(), snprintf(), respectively, except that they are called with a va_list instead of a variable number of arguments. These functions do not call the va_end macro. Because they invoke the va_arg macro, the value of ap is undefined after the call. See stdarg(3).

vsnprintf会修改传入的ap,所以如果程序在第一次调用vsnprintf发现buffer空间不够长之后,再次调用vsnprintf,就会出现未定义行为。

您提供的代码在我的64位linux机器上无法编译,把Makefile中的-march=i686改为-m32之后,测试没有发现问题,但是删掉-m32之后测试也会出现错误。

哈希表没有实现碰撞检测

如果把hash_blob函数的实现改成直接return 1;,然后执行下面两行代码:

CSTRING_LITERAL(foostr0, "bye world");
CSTRING_LITERAL(foostr1, "hello world");

在执行完第一行代码后S.hash[1]里存的是"bye world",然而在执行完第二行代码后S.hash[1]变成了“hello world"。

在函数interning末尾的这行代码si->hash[index] = n;之前,index并没有更新。

There is a memory leak vulnerability

=================================================================
==24927==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 1058 byte(s) in 1 object(s) allocated from:
#0 0x4b9808 (/home/ubuntu/fuzz/cstring/app+0x4b9808)
#1 0x4f13a0 (/home/ubuntu/fuzz/cstring/app+0x4f13a0)

SUMMARY: AddressSanitizer: 1058 byte(s) leaked in 1 allocation(s).

一个问题

我用您写的这个库,cstring_cat连接了一个很长的字符串,最后用char* str = CSTRING(cstr_buf)->cstr;获得了一个char* ,但是strlen(str)的时候,程序就崩溃了,大概几千个字符的时候没任何问题,但是上万了就出问题了?ps:我是新手。
能解答下吗?谢谢!

string_interning的total字段没有更新

cstring库中使用si->total * 5 >= si->size * 4的检测结果来对string_interning的hash表进行扩容,但是我发现total字段从未更新过。我使用如下代码进行测试:

// 在test.c的main方法中
char str[2];
str[1] = '\0';
for (int i = 32; i < 127; i++) {
    str[0] = (char) i;
    cstring_persist(str, 1);
}

// 在cstring.c的129行下面
printf("total: %d, index: %d, size: %d\n", S.total, S.index, S.size);

输出(仅取了最后一行):

total: 0, index: 95, size: 16

测试结果显示total没有更新过,hash表也没有相应扩容,反而是index与interning的短字符串一致。因而我认为可以去掉total字段,用index的值取代之来进行判断。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.