C语言字符串的设计缺陷

redis设计了SDS这一数据结构来表示字符串而不是使用c语言的字符串:字符数组

那么redis为什么要大费周章自己设计字符串呢?

答案是C语言字符串有缺陷

1.获取字符串长度,需要遍历字符数组,时间复杂度是O(N)

2.字符串结尾以"\0"表示,因此字符串内容本身不能包含"\0",因此不能保存二进制数据

3.字符串操作函数不安全,可能会造成缓冲区溢出(这个你一定知道)

我们一一详细介绍这些c语言字符串的缺陷

1.获取字符串长度性能低

由于c语言字符串就是一个以’\0’结尾的字符数组,当你需要一个字符串的长度时,你可能会调用strlen函数,那么这个函数是如何获取字符串的长度的呢?

在这里插入图片描述

strlen会遍历整个字符数组,一直遇到’\0’结束

这个操作的时间复杂度是O(N),对于redis来说代价太大了

redis是怎么解决获取字符串长度的问题的?

在这里插入图片描述

可以看到,对于redis的字符串SDS,不单有保存字符串的数组空间,还有一些额外的成员

len,记录字符串长度,使得获取字符串长度的时间复杂度降到O(1)

2.缓冲区溢出

举个例⼦,strcat 函数是可以将两个字符串拼接在⼀起。

C 语⾔的字符串是不会记录⾃身的缓冲区⼤⼩的,所以 strcat 函数假定程序员在执⾏这个函数时,已经为 dest 分配了⾜够多的内存,可以容纳 src 字符串中的所有内容,⽽⼀旦这个假定不成⽴,就会发⽣缓冲区 溢出将可能会造成程序运⾏终⽌。

Q:redis是如何解决的?

A:SDS的alloc成员,分配给字符数组的空间⻓度。这样在修改字符串的时候,可以通过 alloc - len 计算出剩余的 空间⼤⼩,可以⽤来判断空间是否满⾜修改需求,如果不满⾜的话,就会⾃动将 SDS 的空间扩展⾄ 执⾏修改所需的⼤⼩,然后才执⾏实际的修改操作,所以使⽤ SDS 既不需要⼿动修改 SDS 的空间⼤ ⼩,也不会出现前⾯所说的缓冲区溢出的问题

3.不能保存二进制数据

这个很好理解,由于’\0’代表字符串结尾,会造成读入终止,这个限制使得 C 语⾔的字符串只能保存⽂本数据,不能保存像图⽚、⾳频、视频⽂化这 样的⼆进制数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wjq++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值