简体   繁体   中英

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

In my attempt to load .OBJ -files I load vertex data into std::vectors to send them to the GPU later. I fill three vectors, for normals, vertices and texture coordinates. The size of the normal vector is far higher than the size of the other two vectors, even if its filled with the same number of elements.

Code:

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;
}

Output:

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

This seems highly illogical. The program crashs afterwards with a std::bad_array_new_length exception because the Mesh class cant create an array of size 2958875950 to send to the GPU.

Update:

If I swap the declarations of meshVertices and meshNormals , meshVertices has the wrong size. So the first created vector is affected.

If I use std::list instead of std::vector , everything works.

If I comment out the ....reserve(g.faces.size()*3); lines, a std::bad_alloc is thrown.

The simple answer is that your pointers at the start are pointing to somewhere else, either:

  1. You are casting the "scene" structure.
  2. You have junk or unset pointer in the scene structure for normal vector. Could be that you put junk there far before entring the function.

You did notice the 2958875950 is junk/negative integer?

My guess is that you have a memory corruption bug "somewhere" that is overwriting the meshNormals variable on the stack. The fact that swapping the meshNormals and meshVertices declarations leads to meshVertices becoming bad matches that theory.

To narrow in on the problem you can do a few things:

  1. Comment out all lines in the inner for(auto p : f.points) loop and see if the error still occurs.
  2. Assuming it doesn't, start uncommenting lines one-by-one until the error shows up again.
  3. Try making a minimal, stand-alone test code example that duplicates the problem (it would help immensely if you did this before posting a SO question).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM