左 trim 一个 std::vector 没有内存复制
Left trim an std::vector without memory copy
假设我们像这样将一个 100MB 的大文件读入内存:
std::vector<unsigned char> paddedName = { '0', '0', '0', 'T', 'O', 'M'/*... 100MB+ of data ... */ };
如何 trim 去掉前三个字符并在丢弃旧向量数据的同时得到一个包含填充数据的新向量?
这是复制操作的样子:
std::vector<unsigned char> unpaddedName(paddedName.begin() + 3, paddedName.end());
但我们显然不想复制100MB的内存只是为了从头开始擦除3个字符。
那么有更好的方法吗?
如果必须 vector
,则不能。 vector 维护一个连续的数组,并且只允许您调整它的大小(从末尾添加或删除),而不是它的起点,因此从头添加或删除需要移动剩余的元素。
您可以使用 deque
,它允许从两端移除。或者,您可以安排在将不需要的字符读入向量时跳过它们,而不是稍后删除它们。或者您可以维护自己的 pointer/iterator 到有效数据的开头,并使用它代替 paddedName.begin()
。您可以将其概括为 "view" class,包含一对 pointers/iterators 来表示基础向量的子范围,并使用它来访问您想要的数据。
假设我们像这样将一个 100MB 的大文件读入内存:
std::vector<unsigned char> paddedName = { '0', '0', '0', 'T', 'O', 'M'/*... 100MB+ of data ... */ };
如何 trim 去掉前三个字符并在丢弃旧向量数据的同时得到一个包含填充数据的新向量?
这是复制操作的样子:
std::vector<unsigned char> unpaddedName(paddedName.begin() + 3, paddedName.end());
但我们显然不想复制100MB的内存只是为了从头开始擦除3个字符。
那么有更好的方法吗?
如果必须 vector
,则不能。 vector 维护一个连续的数组,并且只允许您调整它的大小(从末尾添加或删除),而不是它的起点,因此从头添加或删除需要移动剩余的元素。
您可以使用 deque
,它允许从两端移除。或者,您可以安排在将不需要的字符读入向量时跳过它们,而不是稍后删除它们。或者您可以维护自己的 pointer/iterator 到有效数据的开头,并使用它代替 paddedName.begin()
。您可以将其概括为 "view" class,包含一对 pointers/iterators 来表示基础向量的子范围,并使用它来访问您想要的数据。