我试图弄清楚如何在没有 stdlib 的情况下使用 C++ 创建通用容器(gcc -nostdlib -nostartfiles)。我第一次遇到这样的问题,我什至想不出我该怎么做。我需要手动 std::vector 之类的东西,没有“operator new”。谁能给我只有 append()、at() 和 remove() 函数的小资源?谢谢!
问候。
我假设您应该将 std::vector 作为您的指南(如果您正在寻找动态容器)或 std::array。
我还假设您正在查看完整的内存管理(这是特定于平台的,所以如果您不想要任何 C++ 内存运算符,这对您来说是一个问题),一个模板类(再次,使用 std::vector 作为您的指导方针)。
您将看到各种构造函数、运算符、迭代器等,其中很多您可以找到有关设计模式或 stackoverflow 的宝贵信息。
例如,附加意味着您按顺序分配额外的内存,以便有一个连续的块(再次,平台相关?)。
At必须使用某种形式的簿记或索引,以及边界和内存检查。
删除与附加相同的一项。
希望这对您有任何帮助。
编辑:回答您的评论。
使用模板(例如 std::vector 所做的),您无需关心类型,它是类(或类型)管理其内存的责任。
例如,您可以在 Win32 中执行的操作是:
template<class _Ty>
class w32Allocator
{
// deallocate object at _Ptr, ignore size
void deallocate(pointer _Ptr, size_type)
{
VirtualFree(_Ptr, 0, MEM_FREE);
}
// allocate array of _Count elements
pointer allocate(size_type _Count)
{
return (pointer)VirtualAlloc(NULL, sizeof(_Ty) * _Count, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
}
};
注意:上面的代码不是我的,不知道是不是bug。取自这篇文章。在这种情况下,您正在管理对 Win32 堆管理的低级 C 调用。请记住,这是一个棘手的领域。
那么您只需要担心 _Ty 类型的数组,即如果它是一个连续数组(非动态):
_Ty array[number_of_objects];
或者,您可以查看链表(其中每个节点都有一个指向您的对象的指针和一个指向下一个节点的指针),但这可能会破坏连续内存性能。
第一站是实现各种内存管理操作符,可能是malloc()
和free()
(如果你也不能使用这些操作符,事情会变得更有趣):
void* operator new(std::size_t size) {
return malloc(size);
}
void* operator new[](std::size_t size) {
return malloc(size);
}
void operator delete(void* ptr) {
free(ptr);
}
void operator delete[](void* ptr) {
free(ptr);
}
一旦你得到了这些,你就可以像往常一样开始分配内存了。使用您要求的少量操作编写std::vector<T>
偶数应该是一个简单的练习。但是请注意,使用at()
是一个坏主意:掩盖错误的宽接口通常更多的是问题而不是解决方案。