获取数组/向量结束地址的未定义行为?

时间:2017-10-12 21:13:34

标签: c++ vector undefined-behavior

我想编写一个模板函数,它可以使用std::vector将数据传递给C风格的API(在我的用例中专门用于OpenGL)。我想出的代码如下:

template<typename T>
void pass_data(GLuint buffer, std::vector<T> const& data) {
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(T), data.data(), GL_STATIC_DRAW);
}

这似乎是一个简单的解决方案,直到我发现T可能有对齐限制会导致&t[1] - &t[0] != sizeof(T)为真,这意味着此函数无法准确传递整个数组。所以我改写了这个函数来代替:

template<typename T>
void pass_data(GLuint buffer, std::vector<T> const& data) {
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, static_cast<size_t>(&data[data.size()] - &data[0]), data.data(), GL_STATIC_DRAW);
}

但是,我不清楚这种过去一次访问是否安全(我非常确定它的未定义行为)。确保我的函数准确评估向量的字节大小,并将正确的参数传递给基础C-API调用的最佳方法是什么?

注意:我不想讨论我如何[错误]使用OpenGL。我只关注精确建模指针+矢量大小的愿望。

1 个答案:

答案 0 :(得分:4)

是的,data[data.size()]是未定义的行为。

幸运的是,您不需要任何此类内容,因为(char*)&data[1] - (char*)&data[0] == sizeof(T)实际上保证适用于任何类型T。所以回到data.size() * sizeof(T)

但我还要添加一个

static_assert(std::is_trivially_copyable<T>::value, "Invalid type");

更安全一点。