Aku*_*ete 8 c++ vector visual-studio-2010
我刚才被告知,在c ++中使用std :: vector作为异常安全动态数组而不是分配原始数组是常见的...例如
{
std::vector<char> scoped_array (size);
char* pointer = &scoped_array[0];
//do work
} // exception safe deallocation
Run Code Online (Sandbox Code Playgroud)
我已多次使用此约定没有问题,但是我最近将一些代码移植到Win32 VisualStudio2010(之前只在MacOS/Linux上)并且我的单元测试正在破坏(stdlib抛出一个断言)当矢量大小恰好是零.
我知道写一个这样的数组会有问题,但是这个假设打破了这个解决方案作为原始指针的替代.考虑以下函数,n = 0
void foo (int n) {
char* raw_array = new char[n];
char* pointer = raw_array;
file.read ( pointer , n );
for (int i = 0; i < n; ++i) {
//do something
}
delete[] raw_array;
}
Run Code Online (Sandbox Code Playgroud)
虽然可以说是多余的,但上面的代码完全合法(我相信),而下面的代码将在VisualStudio2010上抛出一个断言
void foo (int n) {
std::vector<char> scoped_array (n);
char* pointer = &scoped_array[0];
file.read ( pointer , n );
for (int i = 0; i < n; ++i) {
//do something
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在使用未定义的行为吗?我的印象是operator []没有错误检查,这是std :: vector <>的有效使用.还有其他人遇到过这个问题吗?
--edit: 感谢所有有用的回复,回复人们说它是未定义的行为.有没有办法替换上面的原始数组分配n = 0?
虽然说检查n = 0作为例外情况将解决问题(它会).有许多模式不需要特殊情况(例如上面的原始指针示例),所以可能需要使用std :: vector <>以外的东西吗?
就 C++ 标准而言,operator[]
不保证不检查,只是(与at()
)不保证检查。
您会期望在非检查实现中,&scoped_array[scoped_array.size()]
会在向量分配的数组内或在其末尾生成一个合法指针。这不是明确保证的,但对于给定的实现,您可以通过查看其来源进行验证。对于空向量,可能根本没有分配(作为优化),并且我vector
在标准的部分中看不到任何内容,该部分定义了scoped_array[0]
表 68 以外的结果。
从表 68 开始,您可能会说您的表达式的结果是&*(a.begin() + 0)
,它非法取消引用了一个末端迭代器。如果您的实现的向量迭代器只是一个指针,那么您可能会逃脱 - 如果不是,您可能不会,显然您的不是。
我忘记了参数的结果,&*
即不能取消引用的指针上的是否为无操作。IIRC 从标准中不清楚(某处有些含糊不清),这引发了修复标准以使其明确合法的请求。这表明它实际上适用于所有或大多数已知的实现。
就我个人而言,我不会依赖于此,也不会禁用检查。我会重写你的代码:
char* pointer = (scoped_array.size() > 0) ? &scoped_array[0] : 0;
Run Code Online (Sandbox Code Playgroud)
或者在这种情况下只是:
char* pointer = (n > 0) ? &scoped_array[0] : 0;
Run Code Online (Sandbox Code Playgroud)
在我看来,在不知道大小至少为 n+1 的情况下使用向量的索引 n 是错误的,无论它是否在您禁用检查后在您的实现中实际工作。
归档时间: |
|
查看次数: |
2620 次 |
最近记录: |