0

I have a situation where I have a bunch of class objects whose member variables I need to update over time. The amount of objects I need to have can increase and decrease, and do so rapidly throughout my program's. Because I need to have a resizable array of class objects, I chose to use std::vector. Problem is, my current code crashes after about a minute or so of execution (I'm assuming memory leak or something, but I don't know for sure). Here's an example program I wrote to demonstrate what I am doing:

#include <Windows.h>
#include <iostream>
#include <vector> 


char* names[] = {"Larry", "Bob", "xXx_Quicksc0p3zl33t_xXx", "InsertUnoriginalNameHere", "Idunno"};

class CEnt
{
public:
    const char* name;
    int         health;
};

std::vector<CEnt>   entities;

int main()
{
    while (1)
    {
        int iEntCount = rand() % 1000 + 1;  //Generate random value from 1000 to 2000.  This simulates the changing ingame entity count that I grab

        if (entities.size() != iEntCount)
        {
            entities.resize(iEntCount);
        }

        //Print.ToConsole(TYPE_NOTIFY, "%i", iEntCount);

        for (int iIndex = 0; iIndex < iEntCount; iIndex++)
        {
            CEnt& Ent = entities[iIndex];
            Ent.health =    rand() % 100 + 1;   //Generate random value to fill the objects.  This simulates when I grab values from ingame entities and put them in each object
            Ent.name =      names[rand() % 5 + 1];

            printf("Index: %i    Name: %s  Health: %i\n", iIndex, entities[iIndex].name, entities[iIndex].health);
        }
    }
}

It looks sloppy and it is, but it demonstrates what I am doing. Is there a better way to achieve this? I need to access a container at random points in my code that contains the last updated variables for each object in my vector.

haze
  • 239
  • 2
  • 11
  • Is this all the code? I cannot figure out what you're trying to do. – Tyler Jandreau Jun 12 '13 at 02:43
  • It is sort of all the code. I have a thread responsible for iterating through each of the class objects and updating their member variable values so that I can use them in another part of the code. The program itself is injected into another process, where I get the values I want to assign to these variables and reference later in hooks. Does that make more sense? – haze Jun 12 '13 at 02:52
  • 1
    while (1) will run as fast as the CPU can handle. What are your stopping conditions? Why are you writing a class with one `int` in it? `std::vector` could take place of all that. – Tyler Jandreau Jun 12 '13 at 03:14
  • The int variable is just an example. There are a lot of other variables I have that I cut out for less confusion. I did it in a while loop since I had nowhere else to do it and I need to constantly update these values, as they change a lot. I cut out the conditional that stops the update to prevent confusion. My problem is that I need to store a lot of information about a varying amount of things in a fashion that's easy to reference. My current method of using a vector to handle it is either not done correctly or is not the correct solution. – haze Jun 12 '13 at 03:19
  • Post real code and then maybe I'll be able to help you. I think you cut out too much stuff. – Tyler Jandreau Jun 12 '13 at 03:21
  • I updated the code to pretty much exactly what I have. Would you want an example of where I would call it? – haze Jun 12 '13 at 03:34
  • 1
    @user1822632: Please write a [SSCCE](http://sscce.org/) and update your question - I suspect that you may find that a minimized example will not exhibit the problem for you, so some supposedly insignificant different you left away triggers the issue. – Frerich Raabe Jun 12 '13 at 03:37
  • shouldn't iCount and iEntCount be the same thing? – matt Jun 12 '13 at 03:42
  • Please bear with me, Ill write a simple program that does what I want to demonstrate my needs in a manner that will be clearer to you. – haze Jun 12 '13 at 03:52
  • Updated the OP, is this clear enough? – haze Jun 12 '13 at 04:25
  • This runs correctly and indefinitely for me, after fixing it to work on Linux. What do you mean by *crashes*? Run it under a debugger and post the traceback. – poolie Jun 12 '13 at 04:31
  • 1
    If you replace your `#include ` with `#include ` and `#include `, you could get help from people on other operating systems. – Brendan Long Jun 12 '13 at 04:32
  • And yeah, runs fine for me, using exactly 204 KB of memory. – Brendan Long Jun 12 '13 at 04:33
  • It might just be because of where I am running it. Is this a good way to do this sort of thing I guess is my question. If so, then consider my question solved, it might be something else that is crashing me. – haze Jun 12 '13 at 04:33
  • One tip is, always compile with warnings turned on. For example gcc and I would presume also msvc complain you are assigning constant strings in to the `char *` array `names`, which is dangerous, even if it's not your specific problem here. – poolie Jun 12 '13 at 04:34

1 Answers1

2

One thing that looks suspicious is the

        Ent.name =      names[rand() % 5 + 1];

that is going to choose a value in the range 1..5. But the highest valid name is names[4], and it will read off the end of the array.

I would expect that will make it crash immediately or not at all, but it's possible there's some other variable there that changes and eventually becomes an invalid pointer.

One slightly better way to write that would be

const int n_names = sizeof(names)/sizeof(*names);

....

    Ent.name =      names[rand() % n_names];

although better style might be to put the names themselves in a vector, etc. See for example this question and its many many dupes

Community
  • 1
  • 1
poolie
  • 9,289
  • 1
  • 47
  • 74
  • I get "(null)" as a name sometimes, so I wonder if GCC is automatically NULL-terminating the list and $windows_compiler isn't. – Brendan Long Jun 12 '13 at 04:37
  • I also sometimes get (null). I don't think gcc is specifically null-terminating it to be nice, rather just that that location just happens to contain 0. Many of them do. – poolie Jun 12 '13 at 04:40