Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::vector元素在物理内存中是连续的吗?_C++_Memory_Memory Management_Vector - Fatal编程技术网

C++ std::vector元素在物理内存中是连续的吗?

C++ std::vector元素在物理内存中是连续的吗?,c++,memory,memory-management,vector,C++,Memory,Memory Management,Vector,我的问题类似于,但是我问的问题有点不同 显然,可以将第一个std::vector元素的地址用作C类型数组。这意味着在虚拟内存中,std::vector元素是连续的。但是,如果物理内存是碎片化的,则有可能std::vector实际上在物理内存中被分成许多部分 我的问题是:std::vector元素在物理内存(以及虚拟内存)中是连续的吗?用于在向量中存储数据的内存必须位于连续的地址,因为这些地址对代码是可见的 在大多数现代CPU/OS的典型情况下,这意味着虚拟地址必须是连续的。如果这些虚拟地址跨越页

我的问题类似于,但是我问的问题有点不同

显然,可以将第一个
std::vector
元素的地址用作
C
类型数组。这意味着在虚拟内存中,
std::vector
元素是连续的。但是,如果物理内存是碎片化的,则有可能
std::vector
实际上在物理内存中被分成许多部分


我的问题是:
std::vector
元素在物理内存(以及虚拟内存)中是连续的吗?

用于在向量中存储数据的内存必须位于连续的地址,因为这些地址对代码是可见的

在大多数现代CPU/OS的典型情况下,这意味着虚拟地址必须是连续的。如果这些虚拟地址跨越页面边界,那么物理地址很有可能不再是连续的


我要补充一点,这很少是一个主要问题。在许多情况下,现代系统至少在一定程度上支持这种碎片化的内存使用,直到硬件级别。例如,许多网络和磁盘控制器包括“分散/聚集”功能,操作系统使用页表将缓冲区的虚拟地址转换为物理地址,然后直接向控制器提供大量物理地址,然后,如果从内存传输到外设,它会从这些地址收集数据,如果从外设传输到内存,它会将数据“分散”到这些地址。

不,不能保证在C++的抽象机器中会提供连续的物理内存。下面的抽象和硬件
malloc
可以自由使用不连续的内存


只有您的目标实现才能做出这样的保证,但语言/模型并不关心。它依赖于系统来完成它的工作。

虚拟到物理内存的映射主要由CPU处理,但有内核支持。userland进程无法知道这个映射是什么:您的程序,无论使用何种编程语言,都只处理虚拟内存地址。你不能期望,甚至也没有办法知道,如果跨越页面边界的两个相邻虚拟内存地址在物理内存中是相邻的,那么完全没有必要担心它。

@hsouza:这就是他链接的内容。他似乎在问,操作系统本身是否可以“伪造”连续性,但有“真实”的内存分割;坦白地说,我不明白。在幕后,malloc使用mmap,所以问题是mmap是否可以提供连续的物理内存。你看过这个:@ USE2624967虚拟vs物理内存不是C++关心的东西。如果你在某种典型的操作系统中逃脱了用户空间的世界,潜入内核,不知何故在虚拟内存映射中四处游动,你就不在C++关注的范围之内。几乎所有的用户空间进程的内存都可以在页面边界上“碎片化”,但是用户空间过程不需要关心,无论是C++的STD::vector还是CI中的一个普通数组,都认为问题是关于进程地址空间的。一般来说,操作系统处理这些事情。虚拟地址空间是连续的。存储在
std::vector
中的数据将跨越虚拟地址的连续范围。这些数据的物理位置取决于操作系统。@JonathanLeffler:我希望我能+1编辑原因。“甚至没有任何方法可以找到”-好吧,这通常是不正确的,通常每个操作系统都提供一些方法来找到(尽管可能不清楚或需要自定义驱动程序);另一方面,我同意没有标准的方法来做这样的事情。例如,询问执行上面第一个链接中描述的步骤并将结果返回给它的自定义驱动程序;就使用而言,它可能是内核调试器的前端,或者是黑客工具或其他什么。我的观点是说“没有办法找到”是不正确的,因为没有标准或简单的方法。我知道这是吹毛求疵(事实上,你这里的+1是我的),但我不喜欢绝对不正确的语句。按照这种逻辑,一个userland进程除了在地址空间中写入数据和浪费CPU周期之外,甚至不能在文件上写,也不能在屏幕上显示文本或做任何有意义的工作。我同意,我太挑剔了:);为了解决这个问题,我最初的观点是:没有办法知道virtual=>physical映射是错误的,因为操作系统知道并且进程可以询问操作系统(根据原则,没有理由不提供这些信息——这基本上是无用的);然而,环3中的进程确实无法通过自己的方式知道此映射,因此,如果没有API或驱动程序可为您提供此信息,则它无法知道。我想我们都同意这一点,其余的都是“语义”问题。@MatteoItalia,是的,我理解并同意,原则上,向userland公开这些信息是可能的,但它有什么可能的用途?大多数时候,内核甚至不关心TLB中的确切值,只在CPU要求时遍历页表。我猜这些信息没有向userland公开的原因是,如果你拥有它,你就无法真正利用它做任何有用的事情。老实说,我真的很想把这个设施当作纯粹的好奇心,不管它是否无用。