假设有一个容器v
,使得v.size() == 3
且v.capacity() == 5
,我的理解是调用v.shrink_to_fit()
可以实现目的,如果调用成功,则会导致v.capacity()
变为3。
然而,这样做会带来重新分配内存的代价。
为什么呢?不能在不重新分配剩余内存的情况下释放未使用的内存吗?
可能这个问题源于像new
/delete
和malloc
/free
这样的更原始命令的工作方式。
假设有一个容器v
,使得v.size() == 3
且v.capacity() == 5
,我的理解是调用v.shrink_to_fit()
可以实现目的,如果调用成功,则会导致v.capacity()
变为3。
然而,这样做会带来重新分配内存的代价。
为什么呢?不能在不重新分配剩余内存的情况下释放未使用的内存吗?
可能这个问题源于像new
/delete
和malloc
/free
这样的更原始命令的工作方式。
n
字节,你只能返回n
字节或不返回。m
字节(其中m
< n
)或更糟糕的是,在n
字节的中间返回m
字节,当然是可以提供的,但考虑到正确处理所需的额外复杂度。容器本身不分配/释放内存,而是其分配器进行分配/释放内存。
为了使(向量的)分配器能够释放内存,它需要提供与已分配给向量数据的内存指针完全相同的指针。
这就是向量数据的开头,而不是“不再使用”的数据的开头。
基本上,我们正在谈论这个分配器的分配/释放方法:
pointer allocate( size_type n, const void * hint = 0 );
void deallocate( T* p, std::size_t n );
deallocate
的参数 T* p
将与从 allocate
返回的指针相同 (== 向量数据的开始).这就是向量实现将传递给 deallocate 的内容。[data, data+size]
中的任何指针传递给分配器的 deallocate 方法。可以构造这样一个分配器来处理它。但是,所有其他分配器都需要遵守此 API,包括标准分配器。int* p = new int[100];
delete [] (p + 50); // imagine making this work
shrink_to_fit
_can_重新分配内存,因为请求_can_得到满足。也就是说,调用shrink_to_fit
可能不执行任何操作,但如果需要,它会通过重新分配来进行。 - Enlico