std::vec::shrink_to_fit
会分配一个新的、更小的vec.len()
数据缓冲区,将数据复制到其中,并销毁旧缓冲区吗?还是它会以某种方式指示内存分配器可以释放缓冲区未初始化的部分,并简单地释放该部分内存?这是否取决于内存分配器?
还有一个离题的问题,我很抱歉在这里问,但如果可能的话,为什么我们不将从向量前面弹出实现为一个简单的“从缓冲区开头释放std::mem::size_of<T>()
数量的内存,并将指针增加一”,而不是将所有元素向左移动一个位置呢?
std::vec::shrink_to_fit
会分配一个新的、更小的vec.len()
数据缓冲区,将数据复制到其中,并销毁旧缓冲区吗?还是它会以某种方式指示内存分配器可以释放缓冲区未初始化的部分,并简单地释放该部分内存?这是否取决于内存分配器?
还有一个离题的问题,我很抱歉在这里问,但如果可能的话,为什么我们不将从向量前面弹出实现为一个简单的“从缓冲区开头释放std::mem::size_of<T>()
数量的内存,并将指针增加一”,而不是将所有元素向左移动一个位置呢?
Vec::shrink_to_fit()
使用 Allocator::shrink() 方法来缩小分配(通过内部 RawVec::shrink_to_fit() 方法),该方法可能只是原地调整现有分配的大小而不移动数据,或者它可能返回一个不同的内存块。
你不能通过重新调整大小来从向量的前面弹出元素,因为内存分配不能改变其起始地址,只能改变其长度。
RawVec
的self.buf
上调用shrink_to_fit(self.len)
RawVec
的shrink_to_fit
。它反过来调用下面第#430行实现的RawVec::shrink
self.alloc.shrink
。这是一个不稳定的Allocator特性上的方法现在,这个函数可以由不同的分配器以不同的方式实现。有些可能会执行realloc操作,而有些可能会对内存进行实际缩小,并且不会memmove
任何内容。要了解您的程序使用的是什么,请了解更多关于您的分配器的信息。
如果您查看分配器的方法,您会发现没有shrink_from_start
方法。这是因为该操作并不常见,并且在分配器中实现起来更加困难。这就是为什么使用它来实现Vec::remove(0)
没有太多意义的原因。