为什么这个向量构造函数抛出std :: bad_alloc异常?

时间:2018-03-17 09:26:26

标签: c++ vector bad-alloc

#include <iostream>
#include <vector>

using namespace std;

void test_bad_alloc(unsigned char *start) {
    try {
        vector<int> v = vector<int>(start + 1, start - 13);
    }catch (bad_alloc) {
        std::cout<<"bad alloc"<<std::endl;
    }
}

int main() {
    unsigned char a[20] = {0};
    test_bad_alloc(a);
    return 0;
}

这段代码与我的真实项目类似,我发现它会导致bad_alloc异常,为什么?这个向量的构造函数是不明确的吗?

3 个答案:

答案 0 :(得分:2)

您的程序在尝试评估start - 13时会有未定义的行为。

start指向a数组的第一个元素,因此start - 13会创建一个无效指针,因为它超出了数组的范围。你根本做不到,它也没有意义。你期望指针指向什么,确切地说?

请注意this is undefined behaviour,即使您没有取消引用指针。

在任何情况下,未定义的行为意味着您的程序可以执行任何操作,并且&#34;任何事情&#34;包括抛出随机异常。

事实上,我无法重现std::bad_alloc例外。例如,最新的Clang会抛出std::length_error而最新的Visual C ++会崩溃。它还取决于编译器标志。

在你的情况下可能发生的事情是编译器产生了二进制代码,它只是继续使用无效指针并将其传递给向量构造函数,然后向量构造函数尝试从中创建一个巨大的整数范围,但失败了。

也许你想要这样的东西呢?

void test_bad_alloc(unsigned char *start, unsigned char* end) {
    try {
        vector<int> v = vector<int>(start + 1, end - 13);
    }catch (bad_alloc) {
        std::cout<<"bad alloc"<<std::endl;
    }
}

// ...

test_bad_alloc(a, a + 20);

我也无法帮助但是注意到矢量定义行中的Java主义。你可以而且应该这样写:

vector<int> v(start + 1, end - 13);

答案 1 :(得分:1)

问题在vector<int> v = vector<int>(start + 1, start - 13);

Range Constructor期望

vector (InputIterator first, InputIterator last,
          const allocator_type& alloc = allocator_type());

即。第一个元素到最后一个元素但是,代替SecondIterator,您使用的是start - 13,它位于已分配数组的内存空间之外。

在最好的情况下,它可能也在您的进程的内存空间之外,并且可能导致分段错误,在最坏的情况下,它可能会获取垃圾值,使用错误数据覆盖文件或通过套接字发送错误消息。

答案 2 :(得分:0)

vector<int>(ptr1, ptr2)调用的构造函数是具有两个迭代器的范围构造函数。它尝试为从ptr1开始并在ptr2之前结束的元素分配内存。但是,当您的ptr2小于ptr1时,您将分配负数元素。

由于ptr2=start-13会在分配的数组之外引用,我猜你想要ptr2=start+13