向量和列表在概念上与 C++ 无关。类似的结构可以用 C 实现,只是语法(和错误处理)看起来不同。例如LodePNG实现了一个动态数组其功能与 std::vector 非常相似。示例用法如下:
uivector v = {};
uivector_push_back(&v, 1);
uivector_push_back(&v, 42);
for(size_t i = 0; i < v.size; ++i)
printf("%d\n", v.data[i]);
uivector_cleanup(&v);
可以看出,用法有些冗长,并且需要复制代码才能支持不同的类型。
没什么/机顶盒给出了适用于任何类型的更简单的实现:
double *v = 0;
arrpush(v, 1.0);
arrpush(v, 42.0);
for(int i = 0; i < arrlen(v); ++i)
printf("%g\n", v[i]);
arrfree(v);
它还提供哈希映射,并且它在 C 语言中用于类型安全容器的技巧也可以应用于其他通用容器。
这些方法中的任何一个都可以通过调用来扩展底层存储realloc
(见下文),或者通过分配新存储malloc
并释放旧的free
-- 这相当于如何std::vector
在 C++ 中增加其内存。
然而,许多 C 代码直接使用 realloc 来管理内存:
void* newMem = realloc(oldMem, newSize);
if(!newMem) {
// handle error
}
oldMem = newMem;
注意realloc
如果失败则返回 null,但旧内存仍然有效。在这种情况下,这种常见(且不正确)的用法会泄漏内存:
oldMem = realloc(oldMem, newSize);
if(!oldMem) {
// handle error
}
相比std::vector
以及上面的 C 等价物,简单realloc
方法不提供 O(1) 摊销保证,即使realloc
如果碰巧避免移动内存,有时可能会更有效。