复述,没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(简单动态字符串SDS)的抽象类型,并将SDS用作复述的默认字符串表示:
<>以前10.143.128.165:6379>, SET msg “hello world" 好设置一个关键=味精,value=https://www.yisu.com/zixun/hello世界的新键值对,
键(关键)是一个字符串对象,对象的底层实现是一个保存着字符串“味精”的SDS;
值(值)也是一个字符串对象,对象的底层实现是一个保存着字符串“hello world”的SDS
SDS除了用来保存字符串以外,SDS还被用作缓冲区(缓冲)AOF模块中的 .
复述中定义动态字符串的结构:
/*,, ,*保存字符串对象的结构,, ,*/, struct sdshdr  {,,,,,, ,,,int len;//, buf 中已占用空间的长度,,,,,, ,,,int 自由;//,buf 中剩余可用空间的长度,,,, ,,,char buf[];//,数据空间,,};
1, len变量,用于记录缓冲区中已经使用的空间长度(这里指出复述的长度为5)
2,自由变量,用于记录缓冲区中还空余的空间( )
3,但字符数组,用于记录我们的字符串(记录复述)
C字符串 SDS 获取字符串长度的复杂度为O (N) 获取字符串长度的复杂度为O (1) API是不安全的,可能会造成缓冲区溢出 API是安全的,不会造成缓冲区溢出 修改字符串长度N次必然需要执行N次内存重分配 修改字符串长度N次最多执行N次内存重分配 只能保存文本数据 可以保存二进制数据和文本文数据 可以使用所有& lt; String.h>库中的函数 可以使用一部分& lt; string.h>库中的函数
传统的C字符串使用长度为N + 1的字符串数组来表示长度为N的字符串,所以为了获取一个长度为C字符串的长度,必须遍历整个字符串。
C字符串,不记录字符串长度,除了获取的时候复杂度高以外,还容易导致缓冲区溢出。
假设程序中有两个在内存中紧邻着的字符串s1和s2,其中s1保存了字符串“复述”,二s2则保存了字符串“MongoDb”:
如果我们现在将s1的内容修改为 ,但是又忘了重新为s1分配足够的空间,这时候就会出现以下问题:
原本s2中的内容已经被S1的内容给占领了,s2现在为集群,而不是“Mongodb”。
当需要对一个SDS进行修改的时候,复述,会在执行拼接操作之前,预先检查给定SDS空间是否足够,如果不够,会先拓展SDS的空间,然后再执行拼接操作:
C语言字符串在进行字符串的扩充和收缩的时候,都会面临着内存空间的重新分配问题。
1。字符串拼接会产生字符串的内存空间的扩充,在拼接的过程中,原来的字符串的大小很可能小于拼接后的字符串的大小,那么这样的话,就会导致一旦忘记申请分配空间,就会导致内存的溢出。
2。字符串在进行收缩的时候,内存空间会相应的收缩,而如果在进行字符串的切割的时候,没有对内存的空间进行一个重新分配,那么这部分多出来的空间就成为了内存泄露。
我们需要对下面的SDS进行拓展,则需要进行空间的拓展,这时候复述,会将SDS的长度修改字为13节,并且将未使用空间同样修改字为1节