Reading data into vector, need some1 smarter than me to help

This code is taken off a bigger project, but essentially there's a vector of type Script (my class) called Scr, and when I try to read data from a .txt into it, it crashes because the size is wrong at some point, i'm not sure.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
bool Game::loadScript()
{
    //This loads all the data from a .txt


    std::ifstream scrStream ("script.txt");

    if (scrStream.is_open())
    {
        unsigned long long lines = 0;

        if (scrStream.good())
        {
            //Parse through .txt and see how many lines there are
            // and read data into every object
            int k = 2, j = 0;
            /////////////////THIS PART////////////////////////////
            do
            {
                std :: cout << k << " " << j << " ";
                Scr.resize(k);

                std::cout << Scr.size() <<std::endl;

                scriptSize = k;

                k++;
                j++;
            }
            while(std::getline(scrStream, Scr[j].action));
            /////////////////////THIS PART//////////////////////////////////

            std::cout << "Script succesfully loaded!\n\nScript has "
                      << lines << " / " << scriptSize << " lines filled.\n";
            return 1;
        }
        scrStream.close();
    }
    else
    {
        //Checks for error when opening file
        std::cout << "Unable to open file!\n";
        return 0;
    }
}


Any ideas?
You haven't posted enough information for us to make sense of what you have posted.
While I have no solution for your problem, but I wanted to point out something regarding the resize method you are using so freely in your code. This is equivalently what you are doing:

http://en.cppreference.com/w/cpp/container/vector/resize
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
type *Src; // the underlying implementation of vector

do
{
    std :: cout << k << " " << j << " ";

    /* Scr.resize(k) begin */
    type *ptr = new type[k];
    // copy everything from Src to ptr and delete that heap allocated memory
    type *cursor = &ptr[0];
    for (auto item : Src)
        *cursor++ = item;
    delete Src;
    // Assign Src to new address
    Src = ptr
    /* Scr.resize(k) end */

    std::cout << Scr.size() <<std::endl;

    scriptSize = k;

    k++;
    j++;

} while(std::getline(scrStream, Scr[j].action));


An alternative will be to use the push_back method exposed by the vector class or alternatively reserve memory for your vector so that memory allocations are not as frequent.

This is of course if efficiency is a concern of yours for this application, otherwise you can just ignore the above and continue with the implementation you have
Last edited on
@kbw:
I have attached a header file that might help you make sense of this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#ifndef GAME_HPP_INCLUDED
#define GAME_HPP_INCLUDED
#include <vector>
#include "Functions.hpp"

struct Script
{
    std::string action;              
};

class Game
{

    public:

        void run();

    private:

        //Functions:

            //Script-related
        bool loadScript();

        std::string parseScript();

            //Game-related
        std::string processEvents(std::string toProcess);

        void update(std::string output);

        void display();

        //Variables/objects:

            //Script-related

            unsigned int scriptSize;

            std::vector<Script> Scr;  //<------ this is where I declare the vector

};

#endif // GAME_HPP_INCLUDED 




@Smac89:

Thanks for this. I will use this once I figure out a solution.
It's not clear why you keep resizing the vector. It's normal to "desrialize" or fill in some object, then "push_back" onto the vector.

As you keep resizing the vector, you're never really sure how large it is, right?
Well, the plan is to open a file of unknown size and keep filling the vector as I go along in the file line by line, until we reach end of file.
I'm not sure what you mean , but shouldn't the vector size be in this case 'k', that increases by 1 every time? The problem is that the program runs, gets to the vector size of 2 and then crashes. (AND I HAVE _NO_ IDEA WHY). How can 2 iterations work perfectly fine and the 3rd one fail?
Have you implemented copy/assignment correctly on Script?
I have no idea. What do you mean?

This is how I assign new values from the .txt to the Script objects :

std::getline(scrStream, Scr[j].action) (it's up there in the first batch of code)

Is this what you were referring to?
It would help if you could post class Script so someone can check it. I bet i has a pointer and no proper copy semantics.
I did post it earlier, and it's actually just a simple struct:

1
2
3
4
struct Script
{
    std::string action;              
};
That's crazy, I don't know what's going on. Does this crash with your data?
1
2
3
4
5
6
7
8
9
bool Game::loadScript()
{
	Script s;
	std::ifstream scrStream("script.txt");
	while (std::getline(scrStream, s.action))
		Scr.push_back(s);

	return !Scr.empty();
}
Last edited on
That worked. What the hell is going on.
Oh hang on. This doesn't really help, though. I need the script object to be "alive" for the whole class :/

edit: sorry, i didnt understand how it worked, i think this is good for now! will try a bit more out then mark as solved
Last edited on
Topic archived. No new replies allowed.