# 《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>` 库定义的函数。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET 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?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
