前段时间,我建议我使用std :: vector作为C++中的异常安全动态数组,而不是分配原始数组......例如在空std :: vector上使用运算符[]
{
std::vector<char> scoped_array (size);
char* pointer = &scoped_array[0];
//do work
} // exception safe deallocation
我已经使用这个约定多次,没有任何问题,但是我最近移植一些代码的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;
}
虽然可以说是多余的,上面的代码完全合法(I相信),而下面的代码将抛出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
}
}
断言当时我一直在使用未定义的行为?我在印象运算符[]下没有检查错误,这是对std :: vector <>的有效使用。有其他人遇到过这个问题吗?
- 编辑: 感谢所有有用的回复,回复人们说这是未定义的行为。 有没有办法取代上面的原始数组分配将与n = 0?
虽然说检查n = 0作为例外情况将解决问题(它会)。有许多模式不需要特殊情况(比如上面的原始指针示例),因此可能需要使用除std :: vector <以外的东西?
抛出哪个异常?我没有看到代码错误。 – fschmitt 2010-09-30 10:45:00
@fschmitt:如果向量为空,那么'scoped_array [0]'给出未定义的行为。在这种情况下,使用Visual C++构建一个调试变体,它会失败范围检查并引发异常。 – 2010-09-30 11:28:15
@fschmitt:std :: vector的visual studio实现会触发一个断言(即立即终止整个过程),并显示一个错误,说明向量上出现了一个越界错误。 – Akusete 2010-09-30 11:33:16