一种在 C 语言中不需要结构体且不存储容量的通用动态数组。
A generic dynamic array in C that stores no capacity and needs no struct

原始链接: https://gist.github.com/alurm/2ca14be134d719fe7431217a6b18d91e

这种方法使用简单的双指针数组在 C 语言中实现了一个通用动态数组:一个指针存储长度(转换为 `uintptr_t` 类型),另一个指针指向数据。通过利用 GNU 语句表达式和 C23 特性,该设计消除了对 `IntVec` 等样板结构的需求。 该系统具有内存效率,因为它无需存储容量。相反,它按需计算容量,在长度为零或 2 的幂时触发 `realloc`。虽然这最大限度地减少了开销,但有一个显著的缺点:由于增长逻辑硬编码在 `vec_push` 宏中,每当数组达到 2 的幂阈值时,手动预留的容量都会失效。 总之,这种实现通过利用指针转换和 2 的幂扩展,以牺牲内存管理的灵活性为代价,优先考虑了代码的简洁性和整洁度。

Hacker News 新闻 | 往期 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 一个无需结构体且不存储容量信息的 C 语言通用动态数组 (gist.github.com) alurm 发布于 2 小时前 | 6 分 | 隐藏 | 往期 | 收藏 | 2 条评论 gritzko 9 分钟前 | 下一条 [–] https://github.com/gritzko/libabc/blob/main/Sx.h https://github.com/gritzko/libabc/blob/main/S.md 回复 t-3 10 分钟前 | 上一条 [–] 没有结构体,只是一个实现同样功能的数组,没有字段名或其他便利功能。当你以后不可避免地需要添加、删减或重排字段时,享受不使用结构体带来的“乐趣”吧。 回复 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

The following header shows a way to make a generic dynamic array in C with an array of two pointers:

  • the first pointer stores the length of the dynamic array;
  • the second pointer points to the data.

So, int *vec[2] = { 0 }; is an empty dynamic array of ints. struct person *people[2] = { 0 }; is an empty dynamic array of people.

(uintptr_t)vec[0] is the length of the array, vec[1] is the array.

The vec_push macro pushes a value at the end of the dynamic array and returns true on success.

This code is C23 with statement expressions (a GNU C feature).

First of all, structs aren't used so you don't have to invent names for them (e.g. there is no IntVec). Since a pointer is used to store the length of the dynamic array (as a uintptr_t), this relies on implementation-defined behavior, that is the uintptr_t length read from a pointer must be the same length that was stored.

Second of all, capacity isn't stored at all. Instead, it's computed on demand when the length of the vec is either zero or a power of two. In this case realloc is called with capacity equal to the next power of two greater than the length. The drawback is that it's more difficult to "reserve" elements: during pushing, when the length reaches a power of two, realloc is called for the next power of two no matter what, so a larger manual reservation is effectively discarded.

联系我们 contact @ memedata.com