2011-11-22 174 views
6

这是很牵强的,但下面的代码“安全”(即保证不会造成分段错误):正在访问std :: vector :: reserve safe之后的原始指针吗?

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()?涵盖了相同的主题,但我更感兴趣,如果这是安全并且如果有这样做的陷阱。

编辑:原始代码是错的,用memset代替原来的memcpy

+1

好吧,这是如此丑陋,它伤害。你为什么这样做?如果你真的需要,你不能简单地使用一个数组吗?在这个例子中,100是固定的,所以你可以在堆栈上使用数组而不需要删除[] ing ... – Francesco

+2

“分段错误”是一个特定于平台的事件。 C++语言没有描述它是什么。该语言只是说明是否定义了某些东西,如果是,则说明是做什么的。 –

+1

我已经低估了这个问题,并不是因为我认为这是一个糟糕的问题,而是因为你没有花足够的时间来确保你所问的是你想问的问题(原始代码和当前版本中的代码是相当的不同)。-2个代表点并不多,但应该提醒你在将来稍微小心点,因为当你问别人花时间回答试图帮助的时候,如果你稍后再重新提出问题,那么这段时间会被浪费掉上。 –

回答

16

不,它不安全。

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

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

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

+0

为了指出_why_而提高_why_这是一个糟糕的主意:保留的内存是UB,并且不能通过矢量“正式”使用,直到它已经被调整大小或调整为“push”/“emplaced”为止。 –

2

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

+0

更新我的问题,使用memset而不是'memcpy(我的例子不正确)。 – larsmoa

2

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

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

但是回答这个问题,可能会出现专门为POD类型的工作,如果编译器不使用所分配的空间,任何的问题。当然,如果有人打电话给resize,insert,push_back等,它会吹走你已经写入内存的任何东西,而且矢量的大小也是错误的。没有理由写这样的代码。

相关问题