c - 构建 C 不可变字符串库,如何处理剩余的 const char* 的?

标签 c string

在 C 中处理字符串肯定会让人希望有一种简单的基于类的语言,但我正在尝试构建一个方便的字符串库。我的想法是使用不可变字符串,其结构名为 Rstring(“稳健字符串”),该结构具有内部 const char* s 和 int length code>,这样 rstring_concatrstring_substring 等操作会返回新的 Rstring 对象,并带有自己新 malloc 的字符指针。

在编写该库的初稿时,我对使用我的库而不是 char * 的简单性和整洁性感到满意。然而,我意识到返回一个新分配的指针有点像没有析构函数的 PITA。每次完成某些操作(例如通过连接或子字符串)时,您都会有一些新分配的内存,然后您之前拥有的任何字符串现在都在周围,并且可能毫无用处,因此它们需要空闲 'd,而 C 没有析构函数,因此用户必须手动释放所有内容。

因此我的问题是,是否有任何聪明的方法可以避免必须进行大量手动调用 free?例如,可能有内部 startend 索引,以便让字符串表现得像小字符串,但实际上包含更多内容?我不知道是否有任何普遍接受的方法可以做到这一点,或者人们是否只是陷入了 C 中繁琐的内存管理。

也许最好的是,是否有任何广泛使用的库可以在 C 中方便地进行字符串操作?

最佳答案

如果您需要更好的 C 字符串库,我会推荐 The Better String Library .


C 没有任何方法来简化内存管理。必须释放使用 malloc 分配的任何内存。如果您在一个函数中处理大量字符串,则可以使用特殊的注册表来注册字符串。然后注册表可以销毁所有注册到它的字符串。

例如(只有接口(interface),没有实现)

void rstring_reg_init(rstring_reg*);
void rstring_reg_destroy(rstring_reg*);
rstring rstring_reg_create(rstring_reg*, const char*);
void rstring_reg_register(rstring_reg*, rstring);
void rstring_reg_detach(rstring_reg*, rstring);

如果你的字符串是可变的,你甚至可以使用注册表创建字符串(我宁愿称之为池)。如果字符串要记住它们的池,您甚至可以让它们在创建时注册自己。这可能会产生相当“漂亮的代码”,例如:

rstring f() {
    rstring_reg reg;
    rstring_reg_init(&reg);
    rstring a = rstring_reg_create(reg, "foo");
    rstring b = rstring_reg_create(reg, "bar");
    rstring ab = rstring_concat(a, b);
    rstring s = rstring_substr(ab, 1, 4);
    rstring_detach(s);
    rstring_reg_destroy(&reg);
    return s;
}

这段代码的作用是:

  • 创建注册表
  • 创建都知道注册表的 ab 字符串
  • 创建一个新的 ab 字符串。它会自动添加到注册表中。
  • 创建一个新的s字符串。它还会添加到注册表中。
  • 从注册表中分离s,因为我们想要返回它。
  • 销毁注册表。这会自动销毁 abab
  • 返回s - f 的调用者现在负责管理其内存

最后我宁愿推荐使用 C++ 而不是使用这样的野兽。

你真正想要的是RAII这只能使用 C++ 或专有的 GCC 扩展来实现。

关于c - 构建 C 不可变字符串库,如何处理剩余的 const char* 的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14668679/

相关文章:

c# - 尾数介于 0 和 1 之间的科学计数法的 .NET 格式说明符

iphone - 如何检查字符串是否仅包含 objective-c 中的字母数字字符?

c# - .Net C# String.Join 如果元素值为空,如何输出 "null"而不是空字符串?

c - 如何在不使用任何比较运算符且不使用 if、else 等的情况下以编程方式返回两个整数的最大值?

c - 如何在已安装 OpenSSL 的 Linux 中使用 BoringSSL?

c - x64 处理器上的 C 语法有何不同

c++ - 如何在不公开 C API 的情况下包装 C API?

c - 将 X.509 证书存储在 C 字符串中并将其加载到 SSL_CTX 对象中?

java - 如何使用 Java 正确转义 awk 输入的字符串?

c - c字符串构造