我希望这不是一个太有争议的问题,但我找不到一个适当的完整答案。这也不是关于方法PHAsset.fetch
和reserve
之间的区别或resize
和capacity
之间的区别的问题,这些区别(希望)对我很清楚并经常足够被问到了SO。此外,这不是一个问题,如果这是一个好的做法,它不是!
考虑以下情况:
size
我首先创建一个#include <vector>
#include <iostream>
struct Foo
{
double a, b;
};
int main(int argc, char* argv[])
{
std::vector<Foo> Vec;
Vec.reserve(100);
Foo foo;
foo.a = -13.131;
foo.b = 3.141;
for(int i = 0; i < 100; ++i)
Vec[i] = foo;
for(int i = 0; i < 100; ++i)
std::cout << Vec[i].a << std::endl;
return 0;
}
Foo和保留内存,但不要调整向量的大小。显然std::vector
,但是已经分配了100个元素的内存,现在我的程序可以自由使用,所以从技术上讲,写入和读取这些元素的内存中的任何位置都不会导致分段错误,是正确的吗?
我试图在Ubuntu 14.04上运行这个代码,一切都按预期工作,所有100个元素都已成功写入,所有输出也是-13.131,即使矢量大小保持为0.如果我查找了很多在SO上的答案,他们都正确地指出它导致未定义的行为,因为元素没有被初始化,但它实际上可能以任何方式导致分段错误(不是谈论访问向量中的单位化指针的元素等) ?
有人提出类似这样的问题here这似乎证实了我的想法,但它原则上是否适用于支持C ++编译的所有平台?
答案 0 :(得分:3)
一旦你有未定义的行为,那就是未定义的行为。 未定义行为的一个关键方面是您无法确定不同系统和编译器的行为。现在您可以查看特定编译器的代码和特定的库实现,您将看到它按预期运行。
但我认为你不会发现任何愿意打赌这会影响所有不同系统,编译器和库实现的人。
例如,如果特定的矢量实现决定使用保留的内存作为内部信息怎么办?也许这不太可能,但你怎么能确定没有系统真正这样做呢?
答案 1 :(得分:0)
让我们考虑一个具体的例子 - std :: vector实现,当调用reserve()时,它会分配内存,但后来开始在后台线程上执行复制 - 因为它可以... shrugs 谁知道在不久的将来会发生什么!因此,在复制时,所有读取都被解锁并直接进入旧的存储区域,因为这仍然适合阅读。
现在尝试读取超出范围的内容将尝试读取随机内存,而不是您声明的内容应该是您新分配的内存。
正如评论和其他答案所说,undefined未定义。