Redis 简单动态字符串和传统字符串对比(三)

55 阅读1分钟

1、C 传统字符串为什么二进制不安全?

  • C 字符串除了字符串的末尾之外,字符串里面不能包含空字符串(因为 传统 C 字符串就是通过空字符来判断是否结束) ,如图:

#include <stdio.h>
#include <string.h>

int main() {
    // 使用传统 C 字符串,包含 null 字符和二进制数据
    char data[] = { 'H', 'e', 'l', 'l', 'o', '\0', 'w' };
    printf("输出结果: %s\n", data);
    printf("字符长度: %ld\n", strlen(data));

    return 0;
}

2、SDS 为什么时二进制安全的?

SDS 使用 len 属性记录的长度来判断字符是否结束,而不是通过空字符来判断,如图所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义 SDS 结构体
typedef struct sds {
    int len; // 字符串长度
    int free; // 剩余空间
    char buf[]; // 字符数组
} sds;

// 创建 SDS 字符串
sds* sds_new(const char* init, int len) {
    sds* s = malloc(sizeof(sds) + len); // 加上结构体本身大小
    if (!s) return NULL;
    memcpy(s->buf, init, len);
    s->len = len;
    s->free = 0;
    return s;
}

// 释放 SDS 字符串
void sds_free(sds* s) {
    free(s);
}

// 输出 SDS 字符串
void sds_print(const sds* s) {
    printf("Length: %d, Free: %d, Content: ", s->len, s->free);
    for (int i = 0; i < s->len; ++i) {
        printf("%c", s->buf[i]);
    }
    printf("\n");
}

int main() {
    // 使用 SDS 字符串
    const char data[] = { 'H', 'e', 'l', 'l', 'o', '\0', 'w' }; // 包含 null 字符和二进制数据
    sds* s = sds_new(data, sizeof(data)); // 创建 SDS 字符串
    sds_print(s); // 输出 SDS 字符串
    sds_free(s); // 释放 SDS 字符串

    return 0;
}