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. 学生管理系统 Python语言

    def show_student(): print(('*'*20).center(55)) print('1.添加学生信息'.center(50)) print('2.修改学生信息'.center( ...

  2. ZOJ - 3962 - Seven Segment Display-17省赛-数位DP

    传送门:Seven Segment Display 题意:求一个给定区间每个数字的消耗值的和: 思路:数位DP,有点区间和的思想,还有就是这个十六进制,可以用%llx读,还是比较难的: 还有就是到最大 ...

  3. Atcoder E - Meaningful Mean(线段树+思维)

    题目链接:http://arc075.contest.atcoder.jp/tasks/arc075_c 题意:问数组a有多少子区间平均值为k 题解:一开始考虑过dp,但是显然不可行,其实将每一个数都 ...

  4. codeforces 572 D. Minimization(dp+ 思维)

    题目链接:http://codeforces.com/contest/572/problem/D 题意:给出一个序列,可以任意调整序列的顺序,使得给出的式子的值最小 题解:显然要先排一下序,然后取相邻 ...

  5. moco 入门及问题解决

    废话不多说 下载: http://repo1.maven.org/maven2/com/github/dreamhead/moco-runner/ 选择最新版本下载jar包 启动: 1:在本地jar包 ...

  6. 设置普通用户输入sudo,免密进入root账户

    满足给开发用户开权限,赋予sudo权限.又不让其输入密码的方式: 方式一: 开始系统内部的wheel用户组, 在/etc/suoers 中编辑配置文件如下: %wheel ALL=(ALL) NOPA ...

  7. idea中applicationContext-dao.xml文件中Cannot resolve file***** :spring xml model validation问题

    访问不了classpath下的文件夹中的文件 解决办法如下:(问题出在我创建的resources文件夹是一个普通的文件夹) 1.本来是普通的文件夹 2.ctrl+shift+alt+s打开如下界面: ...

  8. Java Web总结(二)-- 上传和下载

      在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接 ...

  9. JS枚举对象属性的方法及其区别

    愉快的中秋节要过去了,国庆倒计时两个周!!! 闲话不多说,那今天我们来看一看JS中枚举对象属性的方法有哪些以及他们的区别 首先在JS里面枚举对象属性一共有三种方法 for in: 会遍历对象中所有的可 ...

  10. 明明有class为什么还是报ClassNotFoundException?

    描述 我们修改接口时,习惯发布一个快照版本用于测试.我们的一个服务也是发布了快照版本,然后一个jar程序要依赖这个服务,修改pom文件打包部署后,通过 java -jar 命令执行这个jar程序,然后 ...