我一直将指针视为迭代器的特化,用于对象在内存中连续存储的特定情况。然而,我发现分配器成员类型指针(然后在迭代器和容器上定义相同的成员类型)不需要是真正的指针,但它可能是所谓的花式指针,根据cppreference ,
is used to access objects allocated in address spaces that differ from the homogeneous virtual address space.
这就是我过去所说的迭代器而不是指针,但这不是重点。我想知道如何不需要分配器来分配连续内存。想象一下,将一个自定义分配器传递给 std::vector
,但该分配器不以连续方式分配对象。对我来说,这不再是一个 vector 。如果我不希望对象在内存中连续,我会使用列表而不是带有自定义分配器的 vector 。它们看起来像是一个很大的困惑源,为什么要引入它们?
最佳答案
所以,C++作为一种语言有一个指针的概念。对于任何类型 T*
,该语言都需要某些特定的东西。特别是,sizeof(T*)
是静态确定的,并且所有语言指针都具有相同的大小。
然而,在很久以前,T*
可以使用的东西并不能反射(reflect)硬件功能。想象一下,如果硬件有两个内存池,但这些内存池具有不同的最大大小。因此,如果编译器将 T*
映射到较小的内存池,则不可能有一个 T*
指向较大的内存池。毕竟,较大内存的地址空间将超过 T*
的大小。
这导致了 things like LONG_POINTER
的使用等等“指向”T*
可访问空间之外的内存。
allocator::pointer
概念的目标是能够编写一个分配器,允许任何分配器感知的容器与此类非 T*
一起工作-透明兼容的内存池。
当然...这对于大多数硬件来说不再相关。虚拟内存、32 位和 64 位寻址等现在已成为标准。因此,如果存在无法直接访问的内存并且您想要对其进行寻址,则期望您可以通过操作系统调用将此类内存转换为虚拟地址,然后可以将其与语言指针一起使用。请参阅文件和 GPU 内存的映射。
它的目的是解决库级别的问题,但问题却在硬件/操作系统级别得到解决。因此,这是分配器和分配器感知容器不必要的复杂化,但由于近 25 年前做出的决定,它仍然存在。
关于c++ - 为什么存在奇特的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62700637/