`
乱蓬头199303
  • 浏览: 81977 次
文章分类
社区版块
存档分类
最新评论

谈谈Go语言的字符串设计

go 
阅读更多

摘要: 本文来自:http://www.ttkmwl.com 最给力的程序源码下载论坛 -通天源码论坛 『问题描述』 那天有用户向我反馈在使用 GoJieba 的过程中发现内存泄露的Bug。 具体现象就是这个测试代码 test.go 跑着跑着内存一直增长。

本文来自:http://www.ttkmwl.com 最给力的程序源码下载论坛 -通天源码论坛

 

『问题描述』

那天有用户向我反馈在使用 GoJieba 的过程中发现内存泄露的Bug。 具体现象就是这个测试代码 test.go 跑着跑着内存一直增长。 刚开始以为是代码里面的C语言部分内存没有正确释放导致的, 查了很久一直没有找到问题所在。

最后发现这个Bug非常白痴,是因为 C.CString 使用不当导致的。 在调用了 C.CString 之后需要手动释放内存。 这个Bug非常白痴,但是却反映了我之前对Go语言string理解不彻底的隐患。 才导致在我第一眼看到 C.CString 的时候, 就下意识的认为这个函数肯定没有动态申请新的内存, 和 C++ string::c_str() 一样,复用了内存。 所以也就肯定不需要手动释放。 当然这些只是『我以为』。

『问题深扒』

C语言和Go语言本是同根生嘛, 所以Go语言在设计的时候就通过cgo对C语言调用支持得很好。 而Go语言和C语言之间的数据转换就是通过 C.CString (Go->C), C.GoString(C->Go) 来进行的。

先谈谈 C.GoString ,很显然当使用 C.GoString 的时候, 会复制C语言的*char指针指向的字符串的内容拷贝到Go语言的string管理的内存空间。 Go语言的string管理的内存空间有gc管理,不需要用户主动释放内存。 也就是不需要管它。

而 C.CString 将 Go语言 string 转换成 C语言字符串的时候。 我们就要谈谈为什么它不会像 C++ 的 string::c_str() 一样只是单纯的共用内存了。

本质原因在于对于 Go 来说, string 和 C语言最大的不同是: 在C语言中,字符串是以 ’\0’ 结尾。 其实我认为这个本身是一种历史遗留问题。

『C语言的字符串主要有两种存储方式可选』

比如一个 “hello” 的字符串。 我们在内存中表示可以有两种选择:

第一种:

第二种:

1

2

3

4

typedef struct {

    char* buffer;

    size_t len;

} string;

 

C语言默认的字符串选择了第一种方式, 我认为主要原因在于当年C语言发明的时候是内存和稀缺的时代。 第一种方式比第二种方式显然更省内存。

但是随着时代的发展,内存越来越便宜。内存已经越来越不是程序开发的瓶颈。 第二种方式越来越成为字符串设计的首选。 比如在Nginx之类的著名开源项目中,也是采用了第二种方式对字符串进行存储。

而第二种方式更受青睐的主要原因我认为有两点:

『1. 更好的内存共享』

比如有一个字符串s1 = “hello world” , 而有两种字符串s2 s3 分别是 s1 的子串:"hello", “world” . 当我们使用第二种方式存储字符串的时候, 我们对于s2 s3就直接复用 s1的内存即可。 无需动态分配和释放,这样的场景在协议解析,比如HTTP包头的场景下特别常用。

而假设我们使用第一种方式存储字符串的话, 那么 s1 = “hello world\0”, s2 = “hello\0”, 虽然 s2 是 s1 的子串,但是因为 “\0” 结尾符的存在, s2 就无法复用 s1 的内存,而是需要新申请一段新的内存。 这也是为什么在Go语言中, C.CString 函数返回的内存肯定是一段新的内存, 也就不得不要求调用者手动释放。

『2. 性能更高,获取长度不再是strlen这种O(N)时间复杂度的函数』

这点就比较显而易见了。

​​​​​​​

原文链接

分享到:
评论

相关推荐

    c 语言字符串逆序 c 语言字符串逆序

    c 语言字符串逆序 c 语言字符串逆序c 语言字符串逆序 c 语言字符串逆序c 语言字符串逆序 c 语言字符串逆序c 语言字符串逆序 c 语言字符串逆序c 语言字符串逆序 c 语言字符串逆序c 语言字符串逆序 c 语言字符串逆序c ...

    汇编语言-字符串匹配

    在本课程设计中,我们聚焦于一个特定的应用场景:字符串匹配。字符串匹配是计算机科学中一个基础但至关重要的问题,广泛应用于文本处理、搜索引擎、数据安全等领域。在汇编语言中实现字符串匹配,能帮助我们深入理解...

    汇编语言实验字符串位置的查找

    ### 汇编语言实验:字符串位置的查找 本文将基于提供的汇编代码,解析如何在汇编语言中实现字符串的输入以及特定字符在该字符串中的位置查找。 #### 数据段 (DATAS) 数据段用于定义程序运行时所需的数据变量: ``...

    汇编语言课程设计 字符串匹配

    在“汇编语言课程设计 字符串匹配”这个主题中,我们将深入探讨如何利用汇编语言来实现字符串匹配算法。字符串匹配是计算机科学中的一个重要概念,广泛应用于文本处理、搜索引擎、病毒检测等多个领域。 字符串匹配...

    x86汇编语言文本字符串查找替换程序

    本文将深入探讨一个使用x86汇编语言编写的文本文件字符串查找与替换程序,以及其设计原理和操作步骤。 一、程序设计基础 1. 指令集:x86汇编语言基于80x86处理器的指令集,如MOV(数据传输)、CMP(比较)、JMP...

    字符串处理系统课程设计.doc

    在这个课程设计中,我们将学习如何设计和实现一个字符串处理系统,该系统具有字符串赋值、字符串长度计算、字符串复制、字符串比较、字符串查找、字符串插入和字符串删除等功能。这个系统使用 C++ 语言编写,旨在...

    C语言字符串转换为Python字符串的方法

    C语言字符串转换为Python字符串的方法 C语言字符串转换为Python字符串是指将C语言中的字符串数据转换为Python中的字符串对象,以便在Python环境中使用。下面详细介绍了C语言字符串转换为Python字符串的方法。 使用...

    C语言字符串练习(习题+答案).zip

    本资源"《C语言字符串练习(习题+答案).zip》"正是针对这一需求而准备的,它包含了C语言字符串操作的专项练习题和对应的答案,帮助学习者巩固和提升在字符串处理方面的技能。 字符串在C语言中扮演着重要角色,它们...

    LabVIEW删除字符串中空格

    LabVIEW是一种图形化编程语言,由美国国家仪器公司(NI)开发,主要用于数据采集、测试测量和控制系统的设计。在LabVIEW中,处理字符串是常见的任务之一。本篇将详细讲解如何在LabVIEW中删除字符串中的空格以及计算...

    截取指定长度的字符串

    在实际应用中,我们可能还需要考虑一些边缘情况,例如当截取的长度超过了字符串的实际长度,这时通常会返回整个字符串或者空字符串,具体取决于编程语言的实现。 标签“字符串 截取”提示我们关注的重点在于理解和...

    C++课程设计之string字符串类

    C++课程设计之string字符串类 C++课程设计之string字符串类是C++程序设计中的一部分,主要是通过定义字符串类来实现对字符串的赋值、连接、复制、查找、交换操作。下面是相关的知识点: 一、字符串类的定义 在C++...

    TIA博途-字符转换为字符串以及截取字符串有效字符的具体方法示例.docx

    在处理通信数据时,我们经常需要对字符和字符串进行操作,例如将字符转换为字符串,或者从字符串中截取有效字符。以下将详细介绍在TIA博途中如何实现这些操作。 首先,字符转换为字符串的过程通常涉及到ASCII码。...

    Go-fuzzy提供类似SublimeTextVSCode等风格的模糊字符串匹配Go语言程序包

    "Go-fuzzy"是一个专为Go语言设计的程序包,它实现了类似Sublime Text和Visual Studio Code(VSCode)等流行代码编辑器的模糊字符串匹配功能。这种功能允许用户通过输入部分关键词快速查找和过滤目标字符串,极大地...

    汇编语言查找匹配字符串.zip

    标题“汇编语言查找匹配字符串.zip”所涉及的是一个使用汇编语言编程的任务,目标是实现一个程序,这个程序能够检查用户输入的句子中是否包含特定的关键字,并根据是否存在给出相应的响应。描述中提到,用户将输入两...

    C# 字符串转十六进制串,16进制反向转回原字符串

    字符串是由Unicode字符组成的序列,每个字符在计算机内部通常用16位(2个字节)来表示,可以是英文、数字、标点符号,甚至是中文等多语言字符。十六进制是一种逢16进1的方式,用于表示二进制数,它使用0-9和A-F这16...

    汇编字符串匹配

    ### 汇编语言中的字符串匹配技术解析 在计算机科学领域,字符串匹配是常见的操作之一,尤其是在编程语言中。本文将深入探讨一个基于汇编语言的字符串匹配程序,旨在理解其工作原理及其背后的逻辑。 #### 程序结构...

    数字字符串转BCD码转字符串C函数

    数字字符串转BCD码,BCD码转字符串C函数,定义好的函数下载即可使用无需更改。

    字符串相似度算法 字符串相似度算法 字符串相似度算法

    字符串相似度算法是一种衡量两个字符串之间相似度的方法,广泛应用于自然语言处理、数据挖掘、机器学习等领域。在本文中,我们将讨论一种常用的字符串相似度算法:Levenshtein Distance。 什么是Levenshtein ...

    使用汇编语言,输入字符串,统计其总字符数、字母数、数字数、其他数并输出

    使用汇编语言,输入字符串,统计其总字符数、字母数、数字数、其他数并输出 将字符串输入后,每一位取出比较判断是什么类型的字符,然后对应字符计数器加1,循环结束输出个字符计数器数目与 数组总长 统计字符数

Global site tag (gtag.js) - Google Analytics