在std :: vector :: reserve safe之后访问原始指针?

时间:2011-11-22 14:04:29

标签: c++ stl vector

这是相当牵强的,但是以下代码"安全" (即保证不会导致分段错误):

std::vector<int> vec(1); // Ensures that &vec[0] is valid
vec.reserve(100);
memset(&vec[0], 0x123, sizeof(int)*100); // Safe?

我意识到这很难看 - 我只是想知道它是否技术上安全,而不是“非常好”。我猜它唯一的用法可能是忽略存储在给定索引之外的值。

请注意! How can I get the address of the buffer allocated by vector::reserve()?涵盖了相同的主题,但如果这是安全并且存在陷阱,那么我会更感兴趣。

编辑:原始代码错误,将原始memcpy替换为memset

3 个答案:

答案 0 :(得分:16)

不,这不安全。

reserve()之后,保证向量不会重新分配存储,直到达到capacity()

但是,该标准没有说明向量实现可以对size()capacity()之间的存储做什么。也许它可以用于一些内部数据 - 谁知道?也许地址空间只是保留而不是映射到实际的RAM?

访问[0..size]之外的元素是未定义的行为。 可以进行一些硬件检查。

答案 1 :(得分:2)

向量重新分配使现有指针,引用等无效。预留可以触发重新分配(23.3.6.2,[vector.capacity])但是你要取的地址是第一个元素最终重新分配之后(在这种情况下根本不会发生,但除此之外)。所以我发现代码没有问题。

答案 2 :(得分:2)

首先请注意,memset会将0x123截断为单个字节并写入,而不是写入四字节模式。

然后,不要这样做,只需使用容器:std::vector<int> vec(100, whatever_value_you_want);

但是要回答这个问题,如果编译器没有为任何事情使用分配的空间,它可能看起来特别适用于POD类型。当然,如果有人打电话给resizeinsertpush_back等,那么它会将您已经写入内存的任何内容都吹走,并且矢量的大小也会出错。没有理由编写这样的代码。