专栏名称: IT服务圈儿
关注互联网前沿资讯,提供最实用的学习资源。我们是有温度、有态度的IT自媒体平台。
目录
相关文章推荐
爱可可-爱生活  ·  【AI-Powered Podcast ... ·  22 小时前  
国际金融报  ·  马斯克寻求收购OpenAI,奥尔特曼回应 ·  昨天  
金融早实习  ·  平安资管2025社会招聘 ·  2 天前  
51好读  ›  专栏  ›  IT服务圈儿

首版Git源码初探——Linux之父在malloc之后也忘了free啦?

IT服务圈儿  · 公众号  ·  · 2025-02-03 17:30

正文

来源丨经授权转自 经授权转自 计算机奇闻逸事

作者丨胡译胡说

Linus Torvalds 无疑是开源软件界最具影响力的人物之一。作为 Linux 内核的创始人,他因技术贡献赢得了尊敬,但也常因口无遮拦的言辞引发争议。

Linus 对代码质量的要求极其严苛,也许正是因为自信能够写出完美的代码,才让他有底气挖苦和讽刺其他开发者吧。

Linus 写出的代码到底能有多么精简、多么高深、多么优雅、多么健壮……?可能很多程序员都对此充满好奇。Linux 内核的代码显然过于复杂,不适合“鉴赏”。不过,好在 Linus 还在 2005 年 4 月(和 BitKeeper 闹翻之后)编写过 Git 的原型,而且 Git 最初版本的源代码(https://github.com/git/git/commit/e83c5163316f89bfbde7d9ab23ca2e25604af290)只有千行左右,算上 README 和 Makefile 才只有 11 个文件。这可真是揭晓答案的好机会。

  1.  $ wc -*.*.| sort

  2.    23 cat-file.c

  3.    43 read-tree.c

  4.    51 init-db.c

  5.    66 write- tree.c

  6.    81 show-diff.c

  7.    93 cache.h

  8.   172 commit-tree.c

  9.   248 update-cache.c

  10.   259 read-cache.c

  11.  1036 total

不过,要是把这些源文件通读一遍还是需要花些功夫的。那就再从中挑一个最简单的来看一看。毕竟齐白石画只虾、画个萝卜也是名作。

最简单的应该是 init - db . c 了(别光看 cat - file . c read - tree . c 的行数少,那里面调用的函数可复杂了)。经过编译后, init - db . c 形成了一个叫作 init - db 的命令。

试着运行一下就会发现,该命令的功能非常单一,类似现在的 git init ,仅仅是先在当前目录中创建一个隐藏目录 . dircache ,然后在里面创建 objects 目录,以及以两位十六进制数命名、名称依次为 00 ff 的 256 个子目录。

对照着功能再来欣赏下 Linus 亲自操刀的 init - db . c 的代码,

代码非常直观,①先调用 mkdir () 创建了 . dircache ,然后创建了 . dircache / objects ②,最后利用 for 循环,创建了 256 个名字依次为 00 ff 的、 . dircache / objects 中的子目录。

但请注意这一行 path = malloc ( len + 40 ); 。这里动态分配了一块内存,大小为 len + 40 ,用于存储以十六进制数命名的子目录的路径。

稍有 C 语言编程经验的程序员都会牢记一条法则,如果使用 malloc () 分配了内存,但 忘记调用 free () 来释放,就会造成内存泄漏 。只要大学还在使用谭浩强的 C 语言教材开蒙,就是毫无项目经验的大一新生,也会因多次听到老师强调这一点,而囫囵吞枣地记住要 free () 吧。大名鼎鼎的 Linus 竟然忘了?

而且,搜索整个项目,可以发现不止一处调用了 malloc (), calloc (), realloc () 来申请内存,

却只 free () 过 1 次!

Linus 是真忘了?这不妥妥地内存泄露吗!

等一等, malloc () 之后 真的一定要 free ()

其实,如果程序运行时间很短(就像 init







请到「今天看啥」查看全文