简单动态字符串(SDS)与C的字符串的区分

C语言中的字符串,遇到'\0'则结尾,用长度N+1的数组维护长度为N的字符串。

而Redis的SDS是

len表示字符串的长度;

free表示空闲的,未分配的空间;

buffer数组是真正的字符串,并且以'\0'结尾。

 

现在我们对比一下他们的差异,这也是一个出镜率很高的面试题。

1,SDS获取字符串长度复杂度O(1),而C的字符串为O(n)。

因为SDS保存了长度在len中,但是C的字符串需要从头到位遍历字符数组。

2,SDS避免了一些C的内存溢出的问题。

 在C中,某些情况下会发生内存溢出的问题。假如两个字符出s1 'hello',s2 'world' 在内存中紧挨着保存着。

如果在没有给s1申请更多内存的前提下,就为s1追加一些字符串,这时就不知情的把s2的数据修改了。

而SDS字符串拼接函数,已经做好了检查长度的问题,如果空间不够,就会先扩展空间。

3,SDS通过free的内存预分配和惰性释放,降低内存分配次数

C的字符串,每当增加长度的时候,都必须申请内存,不然可能内存溢出;

每当减少长度的时候,都要释放内存,不然可能内润泄漏。

而SDS在len+free不够的时候才扩展内存

扩展的规则是 如果len小于 1Mb,则len和free保持一致,这样buffer数组长度为2*len+1;

如果len大于等于1Mb时,free总是分配1MB,这样buffer数组长度为 len+1Mb+1byte;

当SDS字符串长度减少的时候,内存并不会立即回收,而是把内存放到free中。

这样以后再需要增加长度的时候,不需要再申请内存。

4,判断字符串结尾的方式

C的字符串以遇到'\0'作为判断到了字符串结尾,而SDS以len来判断。

这样SDS中间可以包含'\0'

 

posted @ 2019-06-13 15:21  JustDotNet  阅读(445)  评论(0编辑  收藏  举报