SDS 及 C 字符串的区别.pdf

  1. 1、本文档共13页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
SDS 与 C 字符串的区别 根据传统, C 语⾔使⽤长度为 N+1 的字符数组来表⽰长度为 N 的字符串, 并且字符 数组的最后⼀个元素总是 字符 \0 。 ⽐如说, 图 2-3 就展⽰了⼀个值为 Redis 的 C 字符串: C 语⾔使⽤的这种简单的字符串表⽰⽅式, 并不能满⾜ Redis 对字符串在安全性、效 率、以及功能⽅⾯的要求, 本节接下来的内容将详细对⽐ C 字符串和 SDS 之间的区 别, 并说明 SDS ⽐ C 字符串更适⽤于 Redis 的原因。 常数复杂度获取字符串长度 因为 C 字符串并不记录⾃⾝的长度信息, 所以为了获取⼀个 C 字符串的长度, 程序 必须遍历整个字符串, 对遇到的每个字符进⾏计数, 直到遇到代表字符串结尾的 字符为⽌, 这个操作的复杂度为 。 举个例⼦, 图 2-4 展⽰了程序计算⼀个 C 字符串长度的过程。 和 C 字符串不同, 因为 SDS 在 len 属性中记录了 SDS 本⾝的长度, 所以获取⼀个 SDS 长度的复杂度仅为 。 举个例⼦, 对于图 2-5 所⽰的 SDS 来说, 程序只要访问 SDS 的 len 属性, 就可以 ⽴即知道 SDS 的长度为 5 字节: 又⽐如说, 对于图 2-6 展⽰的 SDS 来说, 程序只要访问 SDS 的 len 属性, 就可以 ⽴即知道 SDS 的长度为 11 字节。 设置和更新 SDS 长度的⼯作是由 SDS 的 API 在执⾏时⾃动完成的, 使⽤ SDS ⽆须 进⾏任何⼿动修改长度的⼯作。 通过使⽤ SDS ⽽不是 C 字符串, Redis 将获取字符串长度所需的复杂度从 , 这确保了获取字符串长度的⼯作不会成为 Redis 的性能瓶颈。 ⽐如说, 因为字符串键在底层使⽤ SDS 来实现, 所以即使我们对⼀个⾮常长的字符 串键反复执⾏ STRLEN 命令, 也不会对系统性能造成任何影响, 因为 STRLEN 命令 的复杂度仅为 。 杜绝缓冲区溢出 除了获取字符串长度的复杂度⾼之外, C 字符串不记录⾃⾝长度带来的另⼀个问题是 容易造成缓冲区溢出 (buffer overflow )。 举个例⼦, string.h/strcat 函数可以将 src 字符串中的内容拼接到 dest 字 符串的末尾: char *strcat(char *dest, const char *src) 因为 C 字符串不记录⾃⾝的长度, 所以 strcat 假定⽤户在执⾏这个函数时, 已经 为 dest 分配了⾜够多的内存, 可以容纳 src 字符串中的所有内容, ⽽⼀旦这个假 定不成⽴时, 就会产⽣缓冲区溢出。 举个例⼦, 假设程序⾥有两个在内存中紧邻着的 C 字符串 s1 和 s2 , 其中 s1 保存 了字符串 Redis , ⽽ s2 则保存了字符串 MongoDB, 如图 2-7 所⽰。 如果⼀个程序员决定通过执⾏: strcat(s1, Cluster) 将 s1 的内容修改为 Redis Cluster , 但粗⼼的他却忘了在执⾏ strcat 之前 为 s1 分配⾜够的 间, 那么在 strcat 函数执⾏之后, s1 的数据将溢出到 s2 所 在的 间中, 导致 s2 保存的内容被意外地修改, 如图 2- 所⽰。 与 C 字符串不同, SDS 的 间分配策略完全杜绝了发⽣缓冲区溢出的可能性: 当 SDS API 需要对 SDS 进⾏修改时, API 会先检查 SDS 的 间是否满⾜修改所需的要 求, 如果不满⾜的话, API 会⾃动将 SDS 的 间扩展⾄执⾏修改所需的⼤⼩, 然后 才执⾏实际的修改操作, 所以使⽤ SDS 既不需要⼿动修改 SDS 的 间⼤⼩, 也不会 出现前⾯所说的缓冲区溢出问题。 举个例⼦, SDS 的 API ⾥⾯也有⼀个⽤于执⾏拼接操作的 sdscat 函数, 它可以将 ⼀个 C 字符串拼接到给定 SDS 所保存的字符串的后⾯, 但是在执⾏拼接操作之 前, sdscat 会先检查给定 SDS 的 间是否⾜够, 如果不够的话, sdscat 就会先 扩展 SDS 的 间, 然后才执⾏拼接操作。 ⽐如说, 如果我们执⾏: sdscat(s, Cluster) 其中 SDS

您可能关注的文档

文档评论(0)

xuefei111 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档