Enr*_*lis 7 c++ memory-management allocation
给定一个v带有v.size() == 3and的容器v.capacity() == 5,我的理解是v.shrink_to_fit() 可以完成对 的调用,如果是,它会导致v.capacity()变为 3。
然而,这是以重新分配为代价的。
为什么?是否可以释放未使用的内存而不为剩余的内存重新分配一块内存?
可能这个问题的根源在于更原始的命令(如new/delete和malloc/ )如何free工作。
底层内存管理系统定义了什么是可能的,通常,它们不允许返回部分分配的内存:如果你有n字节,你要么返回n字节,要么什么都不返回。
返回最后一个m字节(使用m< n),或者更糟的是,返回m字节中间的n字节,当然是可以提供的,但要考虑正确处理它所需的额外复杂性。
当然,可能有一些确实提供了它,但是您的 C++ 编译器和语言定义不一定知道操作系统中哪些在它下面运行,因此他们必须接受需要重新分配的可能性。请注意,他们不保证它会被需要——他们只是期待它。
容器不会在自己身上分配/释放内存,但它是分配器来做的。
为了使(向量的)分配器能够释放内存,需要为其提供与它为向量数据分配的内存指针完全相同的指针。
这是矢量数据的开始,而不是“不再使用”数据的开始。
基本上,我们谈论的是这个分配器的分配/解除分配方法:
pointer allocate( size_type n, const void * hint = 0 );
void deallocate( T* p, std::size_t n );
Run Code Online (Sandbox Code Playgroud)
的参数T* p的deallocate将是相同的从返回的指针allocate(==开始向量的数据的)。这是向量的实现将传递给解除分配的内容。
有一个自定义的向量实现肯定是可以想象的,他可以将范围内的任何指针传递[data, data+size]给分配器的解除分配方法。人们可以构建这样一个分配器来处理它。但是所有其他分配器都需要符合这个 API,也是标准分配器。
那么这样的事情就需要能够“工作”:
int* p = new int[100];
delete [] (p + 50); // imagine making this work
Run Code Online (Sandbox Code Playgroud)
这会增加额外的复杂性、性能和其他问题。