Weird crash with dynamic structure

Hello
I create some code that assign values to a dynamic memory structure. I'm not sure why one code works and the other crashes when it assigns a value.

Working Code
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
#include <iostream>

using namespace std;

struct WorldOjectCollisionMap
{
    float size_x;
    float size_y;
    float size_z;
    float origin_x;
    float origin_y;
    float origin_z;
    int lod;
};

int main()
{

    WorldOjectCollisionMap * CollisionBounds = new WorldOjectCollisionMap[100];

    /// Save collisions
    CollisionBounds[0].size_x=100;

    cout << CollisionBounds[0].size_x;

    return 1;

}


Crashes at
CollisionBounds[SaveCollisionObjects].size_x=staticmodelboxcenter.x_;

Not Working code
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    return sqrt((xrange*xrange)+(yrange*yrange));
}

/// Create rocks along a path
int WorldBuild::CreateRockObjectAlongPath(float x, float z, float numberofobjects, float length)
{
    /// Get Needed SubSystems
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    Renderer* renderer = GetSubsystem<Renderer>();
    Graphics* graphics = GetSubsystem<Graphics>();
    UI* ui = GetSubsystem<UI>();

    /// Try to get the node information;
    Scene * scene_;

    scene_ = this -> GetScene();

    Node* terrainNode = scene_ ->GetChild("Terrain",true);

    Terrain* terrain = terrainNode->GetComponent<Terrain>();

    cout << "another path\r\n";

    /// Need variables
    float lengthlimitdistance= length;

    float objectsalongpath=numberofobjects;
    float objectsdistance=lengthlimitdistance/objectsalongpath;
    float objectincrement=1;

    float origin_x=x;
    float origin_z=z;

    float difference_z=0.0f;
    float difference_x=0.0f;

    float position_x=0.0f;
    float position_z=0.0f;

    float newposition_x=0.0f;
    float newposition_z=0.0f;
    float olddistance=0.0f;


    position_x=origin_x;
    position_z=origin_z;

    do
    {
        /// Pick a random directoin
        int direction=rand()%8+1;

        /// Select coordinate change based on random direction
        switch (direction)
        {
        case NORTH:
            difference_x=0;
            difference_z=1;
            break;
        case NORTHEAST:
            difference_x=1;
            difference_z=1;
            break;
        case EAST:
            difference_x=+1;
            difference_z=0;
            break;
        case SOUTHEAST:
            difference_x=1;
            difference_z=-1;
            break;
        case SOUTH:
            difference_x=0;
            difference_z=-1;
            break;
        case SOUTHWEST:
            difference_x=-1;
            difference_z=-1;
            break;
        case WEST:
            difference_x=-1;
            difference_z=0;
            break;
        case NORTHWEST:
            difference_x=-1;
            difference_z=1;
            break;
        }

        /// If distance less then current distance then while continue loop
        if(ComputeDistance(position_x+difference_x, origin_x, position_z+difference_z,origin_z)<olddistance)
        {
            continue;
        }
        else
        {
            /// Create a new position
            newposition_x=position_x+difference_x;
            newposition_z=position_z+difference_z;

            ///  Copy newposition to current positon
            position_x=newposition_x;
            position_z=newposition_z;

            /// Get distance
            olddistance=ComputeDistance(position_x, origin_x, position_z, origin_z);

            /// Try this method to use percentange
            if(olddistance/lengthlimitdistance>(objectsdistance*objectincrement)/lengthlimitdistance)
            {
                objectincrement++;

                /// Add a Rock to the seen - Rock Node
                Node * RockNode = scene_ -> CreateChild("RockNode");

                StaticModel * RockStaticModel = RockNode->CreateComponent<StaticModel>();


                RockStaticModel->SetModel(cache->GetResource<Model>("Resources/Models/Rock1.mdl"));
                RockStaticModel->ApplyMaterialList("Resources/Models/Rock1.txt");

                /// Create Nodes and COmponents
                RockStaticModel->SetCastShadows(true);

                BoundingBox  staticmodelbox = RockStaticModel->GetBoundingBox();
                Vector3  staticmodelboxcenter= staticmodelbox.HalfSize();


                /// Select a possible position to place a Rock
                Vector3 selectPosition=Vector3(position_x,terrain->GetHeight(Vector3(position_x,0.0f,position_z))+staticmodelboxcenter.y_,position_z);

                /// Save collisions
                CollisionBounds[SaveCollisionObjects].size_x=staticmodelboxcenter.x_;
                /*CollisionBounds[SaveCollisionObjects].size_x=staticmodelboxcenter.x_;
                CollisionBounds[SaveCollisionObjects].size_y=staticmodelboxcenter.y_;
                CollisionBounds[SaveCollisionObjects].size_z=staticmodelboxcenter.z_;
                CollisionBounds[SaveCollisionObjects].origin_x=position_x;
                CollisionBounds[SaveCollisionObjects].origin_z=terrain->GetHeight(Vector3(position_x,0.0f,position_z))+staticmodelboxcenter.y_;
                CollisionBounds[SaveCollisionObjects].origin_z=position_z;
                CollisionBounds[SaveCollisionObjects].lod=0;*/

                /// Save object
                SaveCollisionObjects++;

                /// Set Rock position
                RockNode->SetPosition(selectPosition);
                RockNode->SetRotation(Quaternion(Random(360),Vector3(0.0f,1.0f,0.0f)));

                /// Output X, Y
                cout << position_x << " " << position_z << "\r\n";

            }
        }
    }
    while(olddistance<=lengthlimitdistance);

    return 1;
}


Header
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
46
47
48
49
50
51
52
53
#ifndef WORLDBUILD_H
#define WORLDBUILD_H

using namespace Urho3D;


#define WorldOjectCollisionMapLimit  1000

/// Temporary structure
struct WorldOjectCollisionMap
{
    float size_x;
    float size_y;
    float size_z;
    float origin_x;
    float origin_y;
    float origin_z;
    int lod;
};

class WorldBuild : public LogicComponent
{
    /// Define subclass
    OBJECT(WorldBuild)

public:

    /// Construct.
    WorldBuild(Context* context);
    virtual ~WorldBuild();

    /// Register object factory and attributes.
    static void RegisterObject(Context* context);

    int Init(void);

    /// public
    int CreateRockObjectAlongPath(float x, float z, float numberofobjects, float length);
    int CreateTreeObjectAlongPath(float x, float z, float numberofobjects, float length);

protected:

private:
    float ComputeDistance(int x1, int y1, int x2, int y2);

    /// Saved Collision Objects to 0
    int SaveCollisionObjects;

    /// Set world limit of objects to test for collision
    WorldOjectCollisionMap  * CollisionBounds;
};

#endif // WORLDBUILD_H 
What is the value of SaveCollisionObjects?

In general, you shouldn't be using arrays directly, you ought to use a container of some kind, in your case, std::vector. You can then use the range checked index to catch that kind of error at runtime if you choose.
Last edited on
0

so, saying change it to use vectors instead.
Well yes, but that isn't going to change the logic that's causing your crash. You should change the [] array access to .at() with the vector to detect the error.

Again, what is the value of SaveCollisionObjects?
The value starts at 0.


1
2
3
4
5
6
7
8
int WorldBuild::Init(void)
{
    /// Allocate memory
    //WorldOjectCollisionMap * CollisionBounds = new WorldOjectCollisionMap[300];
    CollisionBounds.clear();
    CollisionBounds.resize(1000);
    int SavedCollisionObjects=0;
}


I replaced the code to do

1
2
3
4
5
6
7
8
9
                /// Save collisions
                CollisionBounds.at(SaveCollisionObjects).size_x=staticmodelboxcenter.x_;
                CollisionBounds.at(SaveCollisionObjects).size_x=staticmodelboxcenter.x_;
                CollisionBounds.at(SaveCollisionObjects).size_y=staticmodelboxcenter.y_;
                CollisionBounds.at(SaveCollisionObjects).size_z=staticmodelboxcenter.z_;
                CollisionBounds.at(SaveCollisionObjects).origin_x=position_x;
                CollisionBounds.at(SaveCollisionObjects).origin_z=terrain->GetHeight(Vector3(position_x,0.0f,position_z))+staticmodelboxcenter.y_;
                CollisionBounds.at(SaveCollisionObjects).origin_z=position_z;
                CollisionBounds.at(SaveCollisionObjects).lod=0;


I'm getting thhis error at the command line

1
2
3
4
5
[Mon Dec 29 00:12:31 2014] WARNING: Forcing top alignment because parent element has vertical layout
another path
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check
Aborted (core dumped)


I think that occurs at the first .at(). I think I'm clearing it with the Init.


The header file has in a class

1
2
3
4
5
6
7
8
9
private:
    float ComputeDistance(int x1, int y1, int x2, int y2);

    /// Saved Collision Objects to 0
    int SaveCollisionObjects;

    /// Set world limit of objects to test for collision
    //WorldOjectCollisionMap  * CollisionBounds;
    vector <WorldOjectCollisionMap> CollisionBounds;;


Then the full code is
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

WorldBuild::WorldBuild(Context* context) :
    LogicComponent (context)
{
    //ctor
}

WorldBuild::~WorldBuild()
{

    //dtor
}

/// Register a object
void WorldBuild::RegisterObject(Context* context)
{
    context->RegisterFactory<WorldBuild>();
}

int WorldBuild::Init(void)
{
    /// Allocate memory
    //WorldOjectCollisionMap * CollisionBounds = new WorldOjectCollisionMap[300];
    CollisionBounds.clear();
    CollisionBounds.resize(1000);
    int SavedCollisionObjects=0;
}

/// Computer distance
float  WorldBuild::ComputeDistance(int x1, int y1, int x2, int y2)
{
    float  xrange= x1-x2;
    float  yrange= y1-y2;

    return sqrt((xrange*xrange)+(yrange*yrange));
}

/// Create rocks along a path
int WorldBuild::CreateRockObjectAlongPath(float x, float z, float numberofobjects, float length)
{
    /// Get Needed SubSystems
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    Renderer* renderer = GetSubsystem<Renderer>();
    Graphics* graphics = GetSubsystem<Graphics>();
    UI* ui = GetSubsystem<UI>();

    /// Try to get the node information;
    Scene * scene_;

    scene_ = this -> GetScene();

    Node* terrainNode = scene_ ->GetChild("Terrain",true);

    Terrain* terrain = terrainNode->GetComponent<Terrain>();

    cout << "another path\r\n";

    /// Need variables
    float lengthlimitdistance= length;

    float objectsalongpath=numberofobjects;
    float objectsdistance=lengthlimitdistance/objectsalongpath;
    float objectincrement=1;

    float origin_x=x;
    float origin_z=z;

    float difference_z=0.0f;
    float difference_x=0.0f;

    float position_x=0.0f;
    float position_z=0.0f;

    float newposition_x=0.0f;
    float newposition_z=0.0f;
    float olddistance=0.0f;


    position_x=origin_x;
    position_z=origin_z;

    do
    {
        /// Pick a random directoin
        int direction=rand()%8+1;

        /// Select coordinate change based on random direction
        switch (direction)
        {
        case NORTH:
            difference_x=0;
            difference_z=1;
            break;
        case NORTHEAST:
            difference_x=1;
            difference_z=1;
            break;
        case EAST:
            difference_x=+1;
            difference_z=0;
            break;
        case SOUTHEAST:
            difference_x=1;
            difference_z=-1;
            break;
        case SOUTH:
            difference_x=0;
            difference_z=-1;
            break;
        case SOUTHWEST:
            difference_x=-1;
            difference_z=-1;
            break;
        case WEST:
            difference_x=-1;
            difference_z=0;
            break;
        case NORTHWEST:
            difference_x=-1;
            difference_z=1;
            break;
        }

        /// If distance less then current distance then while continue loop
        if(ComputeDistance(position_x+difference_x, origin_x, position_z+difference_z,origin_z)<olddistance)
        {
            continue;
        }
        else
        {
            /// Create a new position
            newposition_x=position_x+difference_x;
            newposition_z=position_z+difference_z;

            ///  Copy newposition to current positon
            position_x=newposition_x;
            position_z=newposition_z;

            /// Get distance
            olddistance=ComputeDistance(position_x, origin_x, position_z, origin_z);

            /// Try this method to use percentange
            if(olddistance/lengthlimitdistance>(objectsdistance*objectincrement)/lengthlimitdistance)
            {
                objectincrement++;

                /// Add a Rock to the seen - Rock Node
                Node * RockNode = scene_ -> CreateChild("RockNode");

                StaticModel * RockStaticModel = RockNode->CreateComponent<StaticModel>();

                int pick= rand()%2+1;

                if(pick==1)
                {
                    RockStaticModel->SetModel(cache->GetResource<Model>("Resources/Models/Rock1.mdl"));
                    RockStaticModel->ApplyMaterialList("Resources/Models/Rock1.txt");

                }
                else
                {
                    RockStaticModel->SetModel(cache->GetResource<Model>("Resources/Models/Rock2.mdl"));
                    RockStaticModel->ApplyMaterialList("Resources/Models/Rock2.txt");

                }

                /// Create Nodes and COmponents
                RockStaticModel->SetCastShadows(true);

                BoundingBox  staticmodelbox = RockStaticModel->GetBoundingBox();
                Vector3  staticmodelboxcenter= staticmodelbox.HalfSize();


                /// Select a possible position to place a Rock
                Vector3 selectPosition=Vector3(position_x,terrain->GetHeight(Vector3(position_x,0.0f,position_z))+staticmodelboxcenter.y_,position_z);

                /// Save collisions
                CollisionBounds.at(SaveCollisionObjects).size_x=staticmodelboxcenter.x_;
                CollisionBounds.at(SaveCollisionObjects).size_x=staticmodelboxcenter.x_;
                CollisionBounds.at(SaveCollisionObjects).size_y=staticmodelboxcenter.y_;
                CollisionBounds.at(SaveCollisionObjects).size_z=staticmodelboxcenter.z_;
                CollisionBounds.at(SaveCollisionObjects).origin_x=position_x;
                CollisionBounds.at(SaveCollisionObjects).origin_z=terrain->GetHeight(Vector3(position_x,0.0f,position_z))+staticmodelboxcenter.y_;
                CollisionBounds.at(SaveCollisionObjects).origin_z=position_z;
                CollisionBounds.at(SaveCollisionObjects).lod=0;

                /// Save object
                SaveCollisionObjects++;

                /// Set Rock position
                RockNode->SetPosition(selectPosition);
                RockNode->SetRotation(Quaternion(Random(360),Vector3(0.0f,1.0f,0.0f)));

                /// Output X, Y
                cout << position_x << " " << position_z << "\r\n";

            }
        }
    }
    while(olddistance<=lengthlimitdistance);

    return 1;
}
Well, that just proves that SaveCollisionObjects is greater than CollisionBounds.size(), you're going out of bounds. So the next question is why.

The loop that increments SaveCollisionObjects does not check its value, so I'd say there's some wrong with the collision detection algorithm; you need to rethink it to determine why you don't check for number of possible collisions.
I will look again. This morning I uncommented the lines that was a problem (keeping the rest with no modifications) and the code worked as intended. *Shrugging*
Topic archived. No new replies allowed.