C语言字符串的设计缺陷

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,经济版 1GB 1个月
简介: 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 语⾔的字符串只能保存⽂本数据,不能保存像图⽚、⾳频、视频⽂化这 样的⼆进制数据

推荐学习 https://xxetb.xetslk.com/s/p5Ibb

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2天前
|
C语言
C语言学习笔记之初识字符串
C语言学习笔记之初识字符串
18 5
|
2天前
|
C语言
c语言左旋字符串问题(不同方法超详细解答)
c语言左旋字符串问题(不同方法超详细解答)
6 1
|
21天前
|
安全 编译器 C语言
C语言学习记录——字符串相关函数及部分模拟(strcmp、strncmp、strncat、strncpy、strstr、strtok、strerror)
C语言学习记录——字符串相关函数及部分模拟(strcmp、strncmp、strncat、strncpy、strstr、strtok、strerror)
15 1
|
21天前
|
C语言
C语言学习记录——模拟字符串相关函数(strcpy、strlen、strcat)相关知识-const、typedef
C语言学习记录——模拟字符串相关函数(strcpy、strlen、strcat)相关知识-const、typedef
13 1
|
22天前
|
算法 C语言
C语言——oj刷题——字符串左旋和轮转数组
C语言——oj刷题——字符串左旋和轮转数组
14 1
|
28天前
|
存储 C语言
字符串的引用方式在C语言中的探讨
字符串的引用方式在C语言中的探讨
22 5
|
13天前
|
C语言
C语言——字符串操作函数
C语言——字符串操作函数
9 0
|
1月前
|
C语言
C语言基础 - 字符串/字符数组最易错考点
该文探讨了C语言中'\0'字符对字符串和字符数组的重要性,以及`strlen`和`sizeof`的区别。'\0'作为字符串的结束标志,确保了正确打印和计算字符串长度。示例代码显示,未包含'\0'的字符数组打印时可能出现随机值。`strlen`计算字符串长度,不包含'\0',而`sizeof`返回变量或数组的总字节数,包括'\0'。文章还提醒注意转义字符在字符串中的影响,例如`\t`和`\62`。最后总结了字符串和字符数组处理时应注意的要点。
33 0
C语言基础 - 字符串/字符数组最易错考点
|
22天前
|
C语言
C语言——oj刷题——实现字符串逆序
C语言——oj刷题——实现字符串逆序
10 0
|
22天前
|
C语言
C语言——字符串大小写互换
C语言——字符串大小写互换
27 0