为什么 C 的字符串让人难受,以及我怎么修的
来源:eliasebner.com — 2026-09-07
📋 概述
作者一直不满 C 没有现代语言那样的字符串类型,于是写了一个单文件库。他先拆解痛点:C 的字符串是以 NUL 结尾的字符数组,当年这么做是为了省内存并保持语言简单,但由此带来三类麻烦。第一,求长度必须从头数到尾,复杂度是 O(n) 而不是读取已存长度的 O(1),对百万字符的文本要烧掉大量 CPU 周期。第二,想取字符串里的一段——比如 "Hello World" 的第一个词——要么往数据里插一个 NUL(那样原变量就废了),要么复制一份,涉及堆分配与内存拷贝;这类需求本该由「视图」解决。第三,忘记补 NUL 时,strlen 之类的函数会一路读下去,直到撞上随机的 NUL 或被操作系统判定越界杀掉进程。他的解决办法很直接:定义 str_view(不可变数据加长度)与 str_owned(拥有数据加长度)两个结构,配套一整套函数,并把分配统一接到 arena 分配器上,凡是需要分配的函数首参都接收 struct arena *。
🔑 核心要点
- 痛点一:NUL 结尾导致求长度必须逐字节数到结尾,复杂度 O(n) 而不是 O(1)
- 痛点二:想取字符串中的一段(如 "Hello World" 的第一个词)时,要么插入 NUL 要么复制一份,带来分配与拷贝
- 痛点三:忘记补 NUL 时函数会一路读下去,直到撞上随机 NUL 或被系统杀掉进程
- 方案是两个类型:str_view(不可变数据 + 长度)与 str_owned(拥有数据 + 长度)
- 一旦长度与数据始终同步,你随时知道字符串在哪里结束,不必依赖「记得补 NUL」
- 库是单文件,分配统一走 arena 分配器,每个需要分配的函数首参接收 struct arena *
💡 金句
这样你就总是知道字符串在哪里结束,不必再依赖「记得把所有字符串都补上 NUL 结尾」这件事。
👍 0
👎 0
← 返回 Lobsters 首页