> For the complete documentation index, see [llms.txt](https://gitbook.fantasticmao.cn/tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gitbook.fantasticmao.cn/tech/shu-ju-ku/redis/redis-she-ji-yu-shi-xian-bi-ji-jian-dan-dong-tai-zi-fu-chuan.md).

# 《Redis 设计与实现》笔记 - 简单动态字符串

## 数据结构

```c
struct sdshdr {

    // 记录 buf 数组中已使用字节的数量
    // 等于 SDS 所保存字符串的长度
    int len;

    // 记录 buf 数组中未使用字节的数量
    int free;

    // 字节数组，用于保存字符串
    char buf[];

};
```

```
+----+
|free|
|----|
|len |
|----|   +---+---+---+---+---+----+
|buf |-->|'R'|'e'|'d'|'i'|'s'|'\0'|
+----+   +---+---+---+---+---+----+
```

## 与 C 字符串的区别

### 字符数组

使用字节数组保存数据，同时杜绝了缓冲区溢出，并且减少了修改字符串时带来的内存重新分配次数。

### 二进制安全

C 字符串中的字符必须符合某种编码（例如 ASCII），并且除了字符串的末尾之外，字符串里不能包含空字符（'\0'），否则最先被程序读入的空字符将被会误认为是字符串的结尾。因此 C 字符串只能保存文本数据，而不能保存图片、音频、视频、压缩文件这样的二进制数据。

Redis 中的字符串时 **二进制安全** 的：所有 SDS API 都会以二进制的方式处理 SDS 存在在 buf 数组里的数据，程序不会对其中的数据做任何限制、过滤或者假设。因为 Redis SDS 是使用 `len` 属性的值而不是空字符来判断字符串是否结束的。

### 兼容部分 C 字符串函数

SDS 和 C 字符串一样以空字符结尾，因此 SDS 可以重用一部分 `<string.h>` 库定义的函数。
