網站首頁 編程語言 正文
?在redis中對字符串的處理,個人覺得特別的優雅,所以特意寫這篇帖子來分享一下對其的理解。
struct sdshdr {
int len;
int free;
char buf[];
};
len是長度
free是目前空閑的長度
buf是實際存儲的字符數組
很多讀者,第一次見到char buf[],會感到到,這不是數組么,怎么還能不傳入初始大小???
為了用官方的論證這個char buf[],筆者特意找到GCC手冊中6.17 Arrays of Length Zero章節,以下截圖是對其的描述。

一言以蔽之:就是GCC編譯器在ISO C99的C語言規范中支持動態數組。并且初始長度為0。并且只能出現在結構體中最后一個成員。
既然redis定義了自己的字符串形式,那么對字符串的操作那比不可少,所以下面挑選幾個api對其講解。實際上,細心的讀者可以發現,其實每個api的操作大同小異,都是通過指針的騷操作得到sdshdr結構體,然后取值。
sdslen講解
static inline size_t sdslen(const sds s) {
? ? struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
? ? return sh->len;
}
首先需要明白:
sizeof(struct sdshdr) = 8。
因為由GCC文檔得知可變數組在初始化的過程中大小為0,所以sizeof(struct sdshdr) 僅僅是2個int的大小2*4 = 8;
其次方法參數const sds s是傳入的char*地址。也就是sdshdr結構體中char buf[];的地址。
所以使用char buf[];的地址 - 8 就是sdshdr結構體的地址。
文字描述可能存在理解偏差,所以筆者借用圖形化來方便讀者的理解,如下圖所示。
?
?
?sdsnewlen講解
// void *init是初始化的字符串
// size_t initlen是長度
sds sdsnewlen(const void *init, size_t initlen) {
struct sdshdr *sh;
if (init) {
// 因為sizeof(struct sdshdr)長度不計算char buf[],
// 所以開辟大小需要加上initlen,為什么要+1,因為字符串'\0'結尾,所以要+1的大小。
sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
} else {
sh = zcalloc(sizeof(struct sdshdr)+initlen+1);
}
if (sh == NULL) return NULL;
sh->len = initlen;
sh->free = 0;
// 把傳入的字符串拷貝到sdshdr結構體中的char buf[]中。
if (initlen && init)
memcpy(sh->buf, init, initlen);
// 把字符串的最后一位賦值為'\0'
sh->buf[initlen] = '\0';
// 返回char buf[]的地址
return (char*)sh->buf;
}
仔細的講解都在代碼的注釋中。
這里需要注意一點,就是sizeof(struct sdshdr)長度不計算char buf[],所以開辟大小需要加上initlen,為什么要+1,因為字符串'\0'結尾,所以要+1的大小。
其他的api大同小異,就不一一的做講解了。
總結:
最后,如果本帖對您有一定的幫助,希望能點贊+關注+收藏!您的支持是給我最大的動力,后續會一直更新各種框架的使用和框架的源碼解讀~!
原文鏈接:https://blog.csdn.net/qq_43799161/article/details/126306177
相關推薦
- 2023-01-20 Python-with?open()?as?f的用法及說明_python
- 2023-06-17 Python結合Sprak實現計算曲線與X軸上方的面積_python
- 2022-11-14 Python實現簡易超市管理系統_python
- 2023-07-02 jQuery和HTML對某個標簽設置只讀或者禁用屬性的方式_jquery
- 2023-06-05 Python?socket之TCP通信及下載文件的實現_python
- 2022-07-22 URLClassLoader加載Class時的類初始化問題
- 2023-02-15 Android音視頻開發只硬件解碼組件MediaCodec講解_Android
- 2022-09-20 一文詳解C++中動態內存管理_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支