Skip to content
Published at:

C语言中的字符串

c语言的字符串,本质上是一个以\0字符结尾的字符数组,使用起来操作想去繁琐,不少库都会对其进行封装。下面看一些比较有代表性的

典型库里面的字符串的封装:

  • Git里面的strbuf
  • Dbus里面的字符串DBusRealString
  • Glib中的GString
  • nginx中的ngx_str_t
  • Redis中的sds

Git里面的strbuf

c
struct strbuf {
    size_t alloc;
    size_t len;
    char*  buf;
};

Dbus里面的字符串DBusRealString

DbusDBusString包装了一层DBusRealString,对外DBusString,对内DBusRealString

c
typedef struct {
    unsigned char* str;              /**< String data, plus nul termination */
    int            len;              /**< Length without nul */
    int            allocated;        /**< Allocated size of data */
    unsigned int   constant : 1;     /**< String data is not owned by DBusString */
    unsigned int   locked : 1;       /**< DBusString has been locked and can't be changed */
    unsigned int   valid : 1;        /**< DBusString is valid (initialized and not freed) */
    unsigned int   align_offset : 3; /**< str - align_offset is the actual malloc block */
} DBusRealString;

Glib中的GString

c
struct _GString {
    gchar* str;
    gsize  len;
    gsize  allocated_len;
};

nginx中的ngx_str_t

c
typedef struct {
    size_t  len;
    u_char* data;
} ngx_str_t;

Redis中的sds

c
typedef char* sds;

/* Note: sdshdr5 is never used, we just access the flags byte directly.
 * However is here to document the layout of type 5 SDS strings. */
struct __attribute__((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char          buf[];
};
struct __attribute__((__packed__)) sdshdr8 {
    uint8_t       len;   /* used */
    uint8_t       alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char          buf[];
};
struct __attribute__((__packed__)) sdshdr16 {
    uint16_t      len;   /* used */
    uint16_t      alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char          buf[];
};
struct __attribute__((__packed__)) sdshdr32 {
    uint32_t      len;   /* used */
    uint32_t      alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char          buf[];
};
struct __attribute__((__packed__)) sdshdr64 {
    uint64_t      len;   /* used */
    uint64_t      alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char          buf[];
};

SDS:Simple Dynamic Strings

其它几没有太大差别:容量、长度、数据,到是这个SDS SDS是在redis中使用的字符串,后面独立成了单独的仓库:https://github.com/antirez/sds

设计:

+--------+-------------------------------+-----------+
| Header | Binary safe C alike string... | Null term |
+--------+-------------------------------+-----------+
         |
         `-> Pointer returned to the user.

示例:HELLOWORLD

+------------+------------------------+-----------+---------------\
| Len | Free | H E L L O W O R L D \n | Null term |  Free space   \
+------------+------------------------+-----------+---------------\
             |
             `-> Pointer returned to the user.

使用:

todo

其它:

LSB: least significant bit

Updated at: