首页 > 解决方案 > 为什么会有花哨的指针?

问题描述

我一直将指针视为迭代器的一种特化,用于对象连续存储在内存中的特殊情况。但是,我发现 Allocator 成员类型pointer(然后在迭代器和容器上定义相同的成员类型)不需要是真正的指针,但它可能是所谓的花哨指针,根据cppreference

用于访问分配在不同于同构虚拟地址空间的地址空间中的对象。

这就是我以前所说的迭代器而不是指针,但这不是重点。我想知道如何不需要分配器来分配连续的内存。想象一下,将自定义分配器传递给std::vector它不会以连续的方式分配对象。对我来说,这不再是向量了。如果我不希望对象在内存中是连续的,我会使用列表而不是带有自定义分配器的向量。它们只是看起来很混乱,为什么要引入它们?

标签: c++pointersmemory-managementiterator

解决方案


So, C++ as a language has a concept of a pointer. For any type T*, the language requires certain specific things out of it. In particular, sizeof(T*) is statically-determined, and all language pointers have the same size.

In the long-before time however, the things that T* could work with did not reflect hardware capabilities. Imagine if hardware had two pools of memory, but these pools of memory have different maximum sizes. So if the compiler mapped T* to the smaller pool, then one could not have a T* that points to the larger pool of memory. After all, the address space of the larger memory would exceed the size of T*.

This led to the use of things like LONG_POINTER and the like for "pointing" into memory outside of the T* accessible space.

The goal of the allocator::pointer concept is to be able to write an allocator that can allow any allocator-aware container to work with such non-T*-compatible pools of memory transparently.

Of course... that is no longer relevant for most hardware. Virtual memory, 32 and 64-bit addressing, and the like are now standard. As such, if there's memory that's not directly accessible and you want to address it, the expectation is that you'll convert such memory into virtual addresses via OS calls which can then be used with language pointers just fine. See mapping of files and GPU memory.

It was intended to solve a problem at the library level, but the problem was instead solved at the hardware/OS level. Thus, it's an unnecessary complication of allocators and allocator-aware containers, but it remains present because of decisions made nearly 25 years ago.


推荐阅读