Des*_*tor 2 c++ new-operator dynamic-memory-allocation
C++标准第3.7.3.1节说明了这一点
"未指定连续调用分配函数分配的存储的顺序,连续性和初始值."
订单和邻接是什么意思?为什么没有说明?为什么初始值也未指定?
order
表示分配器不限于返回稳定增加或减少的地址(或任何其他模式).这是有道理的,因为内存通常在程序的生命周期中被回收和重复使用多次.可以从分配器询问存储的顺序是以某种方式定义的,但是在代码执行和内存效率方面,相当于相当大的开销的增益很少(如果有的话).
换句话说,如果在A之后分配B,并且在B之后分配C,则A,B和C可以以任何顺序(ABC,BAC,CAB,CBA,......)出现在存储器中.您知道A,B和C的每个地址都是有效的,但仅此而已.
正如@Deduplicator所指出的,在并发编程中存在一个众所周知的问题叫做"ABA问题".这是间接的原因,即新分配的对象原则上可以有任何地址(注意这有点高级).
当您使用比较交换指令以原子方式修改内存位置(例如,在无锁列表或队列中)时,会发生ABA问题.您的假设是比较交换检测到其他人同时修改了您尝试修改的指针.然而,事实是它只检测地址的位模式是否不同.现在可能会释放一个对象并将另一个对象(请求分配器存储)推送到容器,而分配器会返回完全相同的地址 - 这绝对合法.另一个线程使用了compare-exchange指令,它传递得很好.砰!
为了防范这种情况,lockfree结构通常使用带有内置引用号的指针.
contiguity
这是一个类似的约束,它基本上表示在后续分配中分配器返回之间可能存在或不存在"漏洞".
这意味着,如果分配大小为8的对象,然后分配另一个对象,则分配器可能会返回地址A和地址A+8.但它也可能会根据自己的判断返回地址A+10而不是第二次分配.
这是东西,经常与几乎所有的分配情况是因为分配器经常存储元数据,除了实际的对象,通常在"桶"来组织内存下降到一个特定的尺寸(通常16个字节).
因此,如果你分配一个整数(通常是4个字节)或一个指针(通常是4或8个字节),那么在你和你分配的下一个东西之间会有一个"漏洞".
同样,可能要求分配器以连续的方式返回对象,但与相对便宜的东西相比,这将意味着严重的性能影响.
初始值
这意味着您必须正确初始化对象并且不能假设它们具有任何特定值.不,内存不会自动进行零初始化[1].
要求分配器对内存进行零初始化是可能的,但效率会低于可能的(尽管不像其他两个约束那样具有破坏性).