Raistin Kane
Raistin Kane

Reputation: 11

C++ vector do not keep value received from loop

I'm writing a program that takes value from a file. The value require to be modified at further moment, so I store them in some vector.

Basically what the program do is:

Problem is:

As soon the for loop is exited, the vector lost everything. I declared my vector outside the while loop that read the file, so this should not happen. Any one know what is going on?

Example file:

<polylist count="34">
    <input semantic="VERTEX" source="#Cylinder-mesh-vertices" offset="0"/>
    <input semantic="NORMAL" source="#Cylinder-mesh-normals" offset="1"/>
    <vcount>4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 32 4 4 32 </vcount>
    <p>0 0 1 0 3 0 2 0 2 1 3 1 5 1 4 1 4 2 5 2 7 2 6 2 6 3 7 3 9 3 8 3 8 4 9 4 11 4 10 4 10 5 11 5 13 5 12 5 12 6 13 6 15 6 14 6 14 7 15 7 17 7 16 7 16 8 17 8 19 8 18 8 18 9 19 9 21 9 20 9 20 10 21 10 23 10 22 10 22 11 23 11 25 11 24 11 24 12 25 12 27 12 26 12 26 13 27 13 29 13 28 13 28 14 29 14 31 14 30 14 30 15 31 15 33 15 32 15 32 16 33 16 35 16 34 16 34 17 35 17 37 17 36 17 36 18 37 18 39 18 38 18 38 19 39 19 41 19 40 19 40 20 41 20 43 20 42 20 42 21 43 21 45 21 44 21 44 22 45 22 47 22 46 22 46 23 47 23 49 23 48 23 48 24 49 24 51 24 50 24 50 25 51 25 53 25 52 25 52 26 53 26 55 26 54 26 54 27 55 27 57 27 56 27 56 28 57 28 59 28 58 28 58 29 59 29 61 29 60 29 3 30 1 30 63 30 61 30 59 30 57 30 55 30 53 30 51 30 49 30 47 30 45 30 43 30 41 30 39 30 37 30 35 30 33 30 31 30 29 30 27 30 25 30 23 30 21 30 19 30 17 30 15 30 13 30 11 30 9 30 7 30 5 30 62 31 63 31 1 31 0 31 60 32 61 32 63 32 62 32 0 33 2 33 4 33 6 33 8 33 10 33 12 33 14 33 16 33 18 33 20 33 22 33 24 33 26 33 28 33 30 33 32 33 34 33 36 33 38 33 40 33 42 33 44 33 46 33 48 33 50 33 52 33 54 33 56 33 58 33 60 33 62 33</p>
</polylist>

C++ code:

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;
int main(){
    vector<int> meshPrimLengthArray;
    ifstream readCollada("myCollada.dae", ios::in);
    string currentLine("");
    while(getline(readCollada, currentLine)){ //loop that read the file
        if(currentLine.find("<polylist") != std::string::npos){ //the given line tell us on many value the next array will contain, so I can reserve the required space in my vector.
                string numberOfVcount(currentLine.substr(currentLine.find("count=\"")+7, currentLine.find("\">")-(currentLine.find("count=\"")+7)));
                meshPrimLengthArray.reserve(atoi(numberOfVcount.c_str()));
        }
        else if((currentLine.find("<vcount>") != std::string::npos) && (currentLine.find("</vcount>") != std::string::npos)){
            currentLine = currentLine.substr(currentLine.find("<vcount>")+8, currentLine.find("</vcount>")-(currentLine.find("<vcount>")+8));
            istringstream vcountArray(currentLine);
            if(vcountArray){
                for(int i(0); i<(int)meshPrimLengthArray.capacity(); i++){
                    vcountArray >> meshPrimLengthArray[i];
                    cout << " " << meshPrimLengthArray[i] << ","; //show that the value have been inserted into the vector.
                }
                cout << endl << "meshPrimLengthArray.size() = " << meshPrimLengthArray.size() << endl; //show that for some unknow reason the vector have been cleared.
            }
        }
    }
    cout << endl << "Press Enter to continu" << endl;
    cin.get();
    cin.ignore();
    return 0;
}

Upvotes: 0

Views: 313

Answers (1)

LogicStuff
LogicStuff

Reputation: 19607

vcountArray >> meshPrimLengthArray[i]

expects elements to be already constructed, which they aren't. std::vector::reserve does not do that, std::vector::resize does. Your code exhibits undefined behavior.

You also might just use a temporary and std::vector::push_back (that goes together with std::vector::reserve, which makes it potentially faster - avoids reallocations).

Finally, look up the difference between std::vector::size and std::vector::capacity.

If you use operator[], use i < meshPrimLengthArray.size() as loop condition.

Prefer using the right types - size_t in this case, instead of int and a c-style cast!
Of course, this loop can be translated to Range-based for loop.

Upvotes: 1

Related Questions