SDS

前提:在redis中,C字符串只会作为字符串字面量用在一些无须对字符串进行修改的地方,比如打印日志:

redisLog(REDIS_WARNING, “Redis is ready to exit”)

因此,redis构建了一种简单动态字符串(simple dynamic string, SDS)的抽象类型,并将SDS用作redis的默认字符串表示。

比如:

redis> SET msg “Hello World”

OK

其中键值对的键是一个字符串对象,对象底层是一个保存着字符串 ”msg” 的SDS。

键值对的值也是一个字符串对象,对象底层是一个保存着字符串 “Hello World” 的SDS。

SDS的用途总结:

  1. 保存数据库中的字符串值
  2. 用作缓冲区(buffer)
  3. AOF模块中的AOF缓冲区
  4. 客户端状态中的输入缓冲区

下面给出SDS的结构:

struct SDS {

int len; // buf数组中已使用字节数,并未算上’\0’字符

int free;    // buf数组中未使用字节数

char buf[];  // 用于保存字符串

};

SDS与C字符串的区别

  1. O(1)复杂度获取字符串的长度。这个就不需要解释了。

  2. 杜绝缓冲区溢出。比如在使用strcat函数时,在这有个扩充知识要讲,即变量在内存中是如何存储的。

C++将进程内存分为(地址由高到低):栈、堆、BSS(Block Start of Symbol)段,数据段,代码段。其中栈是用来存储局部变量、函数参数和返回地址的,在VS中,栈是由高到低分配内存的(很重要!因为它最特殊0.0);堆是存储动态分配内存的变量的地方,如new和malloc函数就是在这分配内存的;BSS段是用来分配未初始化或初始化为0的全局变量和静态变量;数据段是用来存储初始化值不为0的全局变量和静态变量。代码段则是用来存储代码、静态只读数据的地方。

Ok,有了上面的基础后,让我们来做个实验巩固一下上面的内容。

char s1[] = "Hello";

printf("%p %p\n", s1, &s1[1]);

char *s2 = new char[6];

s2 = "World";

printf("%p %p\n", s2, &s2[1]);

可以明显地看到,局部变量s1和s2的地址区别,由于s2的内存是动态分配的,故其地址值小于s1。此外,我们可以看到,s1字符串在栈中是怎么放置的,起始地址为低地址,说明(低地址->高地址)H->e->l->l->o。

ok,这很明显了,如果我们将s2拼接到s1后面,会发生什么?

由于s1的最后一个字符是在栈顶,那么在拼接后,会返回栈越界错误!这也是strcat函数不安全的地方!而SDS在拼接字符串时,会考虑有没有足够的空间(free字段的用处出现了),具体细节后面再讲,先填坑先orz…

// 这里是全局变量

int a;

int aa = 0;

int b = 1;

const int con = 0;    // 常量

// 到这为止

printf("%p %p\n", &a, &aa);

printf("%p\n", &b);

printf("%p\n", &con);

可以看出,全局变量a,aa,b之间的区别,是不是和我们上面说的一毛一样!当然,常量也是!

到这就可以C++的内存就介绍完了。让我们继续介绍SDS和C字符串的区别吧(汗)

  3. 减少修改字符串时带来的内存重新分配次数。SDS通过未使用空间解除了字符串长度和底层数组长度的关联。(因为SDS的buf数组长度是len+free+1(别忘了’\0’哦)。比如说在剪切字符串时,SDS并不会释放剪切的内存空间,而是增大free。

简单动态字符串(SDS)的更多相关文章

  1. 图解Redis之数据结构篇——简单动态字符串SDS

    图解Redis之数据结构篇--简单动态字符串SDS 前言     相信用过Redis的人都知道,Redis提供了一个逻辑上的对象系统构建了一个键值对数据库以供客户端用户使用.这个对象系统包括字符串对象 ...

  2. Redis底层探秘(一):简单动态字符串(SDS)

    redis是我们使用非常多的一种缓存技术,他的性能极高,读的速度是110000次/s,写的速度是81000次/s.这么高的性能背后,到底是怎么样的实现在支撑,这个系列的文章,我们一起去看看. redi ...

  3. Redis数据结构之简单动态字符串SDS

    Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话, ...

  4. redis 系列3 数据结构之简单动态字符串 SDS

    一.  SDS概述 Redis 没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型,并将SDS用作Redis的默 ...

  5. Redis源码解析:01简单动态字符串SDS

    Redis没有直接使用C字符串(以'\0'结尾的字符数组),而是构建了一种名为简单动态字符串( simple  dynamic  string, SDS)的抽象类型,并将SDS用作Redis的默认字符 ...

  6. Redis5设计与源码分析读后感(二)简单动态字符串SDS

    一.引言 学习之前先了解几个概念: SDS定义:简单动态字符串,Redis的基本数据结构之一,用于储存字符串和整型数据. 二进制安全:C语言中用"\0"表示字符串结束,如果字符串本 ...

  7. Redis核心原理-简单动态字符串SDS

    SDS简介 Redis是C语言编写的,但没有使用c语言的字符串结构,而是自己实现了一套简单动态字符串 simple dynamic string 简称SDS,SDS兼容C语言的字符串类型,原理类似Ja ...

  8. 深入理解Redis 数据结构—简单动态字符串sds

    Redis是用ANSI C语言编写的,它是一个高性能的key-value数据库,它可以作用在数据库.缓存和消息中间件.其中 Redis 键值对中的键都是 string 类型,而键值对中的值也是有 st ...

  9. 【Redis】简单动态字符串SDS

    C语言字符串 char *str = "redis"; // 可以不显式的添加\0,由编译器添加 char *str = "redis\0"; // 也可以添加 ...

  10. Redis 数据结构之简单动态字符串SDS

    几个概念1:key对象 数据库存储键值对的键,总是一个字符串对象.2:value对象 数据库存储键值对的值,可以是字符串对象,list对象,hash对象,set对象,sorted set对象.    ...

随机推荐

  1. 《阿里巴巴Java开发手册1.4.0》阅读总结与心得(三)

      (六)工程结构 (一)应用分层 1. [推荐]图中默认上层依赖于下层,箭头关系表示可直接依赖,如:开放接口层可以依赖于Web 层,也可以直接依赖于 Service 层,依此类推:  开放接口层: ...

  2. windows服务autofac注入quartz任务

    一.nuget下载相关类库引用 install-package Quartz install-package Autofac install-package Autofac.Configuration ...

  3. CodeForces 223C Partial Sums 多次前缀和

    Partial Sums 题解: 一个数列多次前缀和之后, 对于第i个数来说他的答案就是 ; i <= n; ++i){ ; j <= i; ++j){ b[i] = (b[i] + 1l ...

  4. 一起来聊一下 JavaScript 的用途和那些特性

    JavaScript 简介 我们一起来聊一下 JavaScript,用它能做什么,它有哪些特性,以及一些跟它配合使用的技术. 什么是 JavaScript? JavaScript 最初的目的是为了&q ...

  5. 4、cesium场景出图,打印图件

    cesium场景出图,打印图件 把3d渲染的页面进行截图,并可以下载到本地:代码如下: function printscreenScene() { var image = new Image();// ...

  6. 漫谈JavaScript中的提升机制(Hoisting)

    前言 刚接触到JavaScript的时候,便知道JavaScript是按顺序执行的,是如浏览器的解析DOM树一样的流程,解析DOM结构的时候,如果遇到JS脚本或者外联脚本便会停止解析,继续下载脚本之后 ...

  7. Toad客户端连接Oracle数据库报错 ORA-12170:TNS:连接超时

    Oracle 客户端连接Oracle数据库报错   ORA-12170:TNS:连接超时  排错步骤: 1. 查看网络是否畅通:  打开cmd,ping数据库IP 2. 查看端口是否畅通: 打开cmd ...

  8. Docker搭建disconf环境,三部曲之一:极速搭建disconf

    Docker下的disconf实战全文链接 <Docker搭建disconf环境,三部曲之一:极速搭建disconf>: <Docker搭建disconf环境,三部曲之二:本地快速构 ...

  9. Java中Jedis连接Linux上的Redis出现connect time out(解决方案)

    我的代码: /** * * <p>Title: testJedis</p> * <p>Description: 测试单机版的redis连接(每连接一次构建一个对象) ...

  10. 在Linux上安装nginx时遇到的问题,真的好坑啊!!!!

    解决了两个小时愣是卡着没动,结果一请大神问题就迎刃而解,怪自己太粗心,一下午差点就被这个问题安排的明明白白,直接上问题: makeFile时的问题:   checking for OS + Linux ...