vector大小错误,大于元素数

C++: vector size is wrong and higher than the number of elements

本文关键字:大于 元素 错误 vector      更新时间:2023-10-16

在我尝试加载.OBJ -文件时,我将顶点数据加载到std::vectors中,以便稍后将它们发送给GPU。我填充了三个向量,分别是法线、顶点和纹理坐标。法向量的大小远远大于其他两个向量的大小,即使它被相同数量的元素填充。

代码:

SceneTree* generateSceneTree(OBJScene* scene){
    PostProcessing::triangulateFaces(scene);
    SceneNode* node = new SceneNode;
    vector<Vec<3>>& sceneNormals = scene->attributeData[Attribute::Normal];
    vector<Vec<3>>& sceneVertices = scene->attributeData[Attribute::Position];
    vector<Vec<3>>& sceneTexCoords = scene->attributeData[Attribute::TexCoord];
    map<string,MaterialInfo*> mtls;
    for(string s : scene->mtlLibs){
        auto temp = loadMTL(s);
        mtls.insert(temp.begin(),temp.end());
    }
    vector<Vec<3>> meshNormals;      <-- creating vectors here.
    vector<Vec<3>> meshVertices;
    vector<Vec<2>> meshTexCoords;
    for(auto g : scene->groups){
        meshNormals.clear();
            meshNormals.reserve(g.faces.size()*3);
        meshVertices.clear();
            meshVertices.reserve(g.faces.size()*3);
        meshTexCoords.clear();
            meshTexCoords.reserve(g.faces.size()*3);
        AABB bBox;
        cout << "num of faces: " << g.faces.size() << endl;
        for(auto f : g.faces){
            for(auto p : f.points){
                uint vIndex = p.indices[Attribute::Position];
                uint nIndex = p.indices[Attribute::Normal];
                uint tIndex = p.indices[Attribute::TexCoord];
                Vec<3> n = sceneNormals.at(nIndex);
                Vec<3> v = sceneVertices.at(vIndex);
                Vec<3> t = sceneTexCoords.at(tIndex);
                meshNormals.push_back(n);
                meshVertices.push_back(v);
                meshTexCoords.push_back(t.toVec<2>());
                bBox += meshVertices.back();
            }
        }
        cout << "meshNormals size: " << meshNormals.size() << endl;
        cout << "meshVertices size: " << meshVertices.size() << endl;
        cout << "meshTexCoords size: " << meshTexCoords.size() << endl;
        Mesh* m = new Mesh({
            {meshVertices,Attribute::Position},
            {meshNormals,Attribute::Normal},
            {meshTexCoords,Attribute::TexCoord}
        },GL_TRIANGLES);
        SceneLeaf* leaf = new SceneLeaf;
        leaf->nodeData = {Matrix4(),bBox};
        leaf->leafData = {m, mtls[g.mtlName]};
        node->addChild(leaf);
    }
    return node;
}
输出:

num of faces: 1087474
meshNormals size: 2958875950
meshVertices size: 3262422
meshTexCoords size: 3262422

这看起来非常不合逻辑。程序崩溃之后与std::bad_array_new_length异常,因为Mesh类不能创建一个大小为2958875950的数组发送给GPU。

更新:

如果我交换meshVerticesmeshNormals的声明,meshVertices有错误的大小。因此,第一个创建的向量受到影响。

如果我用std::list代替std::vector,一切都工作。

如果我注释掉....reserve(g.faces.size()*3);行,则抛出std::bad_alloc

我的猜测是,你有一个内存损坏的错误"某处",是覆盖meshNormals变量的堆栈。交换meshNormalsmeshVertices声明导致meshVertices变坏的事实与该理论相匹配。

要缩小问题的范围,你可以做以下几件事:

  1. 注释掉内部for(auto p : f.points)循环中的所有行,看看错误是否仍然发生。
  2. 假设没有,开始逐行取消注释,直到错误再次出现。
  3. 试着做一个最小的,独立的测试代码的例子,重复的问题(这将有助于极大,如果你这样做之前张贴一个问题)。

简单的答案是,你在开始的指针指向其他地方,要么:

  1. 你正在铸造"场景"结构。
  2. 你有垃圾或未设置指针在场景结构的法向量。可能是你在进入函数之前就把垃圾放在那里了。

你有没有注意到2958875950是垃圾/负整数?