Memory Leak

Hey all. I am having trouble with, what I believe is a massive memory leak. My goal is to display a 3d sinusoidal surface using OpenGL. To do that I make an XY grid and calculate the "Z" coordinate at each location. I store the vertex locations in a std vector vecv_s and the normal vectors at each vertex in a std vector vecn_s. The objects within are Vector3F objects which simply store the x,y,z components of the mathematical vectors.

I then have to index all of the vertices because I have to draw them in OpenGL in a specific orders. The precise indices are stores in a 2-D std vector in type "int".

I am able to run and display, in real time, with fair performance, when N<100. When N gets too large the rendering slows significantly, and at a certain point the program crashes with "bad_alloc" if N is too large.

Can anyone help me understand what's might be going wrong, or how I can do this more efficientl? I'd like to be able to generate a really fine grid so I can get a great approximation for the fuction. Is 25M quadrilaterals too many? I don't know how many polygons you can expect to render with today's hardware.

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
void SurfaceMesh(){
 int N = 5000;
 int k =0;
 float pi =  3.141592654;
 float xy_increment = .01;
 float x, y, z, nx, ny, nz;
 float freq = .1;

 float norm;
 int amp = 3;
 vector<int> V1;

 for(int i = 0; i<=N; i++){
    for(int j = 0; j<=N; j++){

        x = i*xy_increment-(N+1)/2 *xy_increment;
        y = j*xy_increment-(N+1)/2 *xy_increment;
        z = amp*sinf(freq*x)+amp*sinf(freq*y);

        //Tx = dz/dx
        //Ty = dz/dy
        //N = Tx X Ty
        // N_vec = (-amp*freq*cos(freq*x),   -amp*freq*cos(freq*y),  1)
        // Normalize
        nx= -amp*freq*cos(freq*x);
        ny= -amp*freq*cos(freq*x);
        nz= 1;
        norm = sqrt(nx*nx + ny*ny + nz*nz);
        nx = nx/norm;
        ny = ny/norm;
        nz = nz/norm;
        vecv_s.push_back(Vector3f(x,y,z));
        vecn_s.push_back(Vector3f(nx,ny,nz));


    }

 }
  for(int i = 0; i<=N-1; i++){
    for(int j = 0; j<=N-1; j++){

        V1.push_back(j + i*(N+1));
        V1.push_back((int(i/(N+1))+1)*(N+1)+j + i*(N+1));
        V1.push_back((int(i/(N+1))+1)*(N+1)+j+1 + i*(N+1));
        V1.push_back(j+1 + i*(N+1));
        vecf_s.push_back(V1);
        V1.clear();

    }
  }

}
First I don't see any memory leaks. You're not using any dynamic memory, so memory leaks should not be the problems.

Is 25M quadrilaterals too many?

Probably. 25M * 25M * (sizeof V1 * 4) seems like a very big number to me.

The "bad alloc" is probably because you don't have enough memory for the vector. How big is N when you get this message?

Have you run the program with your debugger to see where the problem is occurring? The compiler should be able to show you where it detected the problems.

By the way why the global variables (vecv_s, vecn_s, vecf_s)? By the way you really should use more meaningful variable names, these three names are so close to being the same that confusion seems inevitable, IMO.
Last edited on
The size of the 2-D grid is N by N. So 5,000*5,000 = 25M. Which means I have 25 million vertices to keep track of. Each vertex has 6 floats associated with it stored in two separate vectors (VECtor of Normals for Surface) and (VECtor of Vertices for Surface).

The 2-D grid will have (N-1)*(N-1) quadrilateral elements, which each have 4 numbers associated with it stored in vecf_s (VECtor of Faces for Surface).

These are all global in scope currently because this function simply "builds" the surface. The surface is drawn (over and over) in another function "DrawScene()" later. It made sense to me to have these vectors global so they never leave scope and have to be rebuilt.

I'm started to learn how to make a game by learning OpenGL (and c++ simultaneously). I'm trying to make the "ground floor", and a simple sinusoidal surface that appeared like hills made sense. I'm having trouble expanding the ground surface without running out of memory.

The debugger is still running, but it's doing something kind of funny in the last loop with V1 in it. It's running particularly slow. Like a few minutes to get through 300 iterations.

Does V1.clear() actually clear that vector from memory? Is this implementation good?


EDIT:

Debugger Failed:

1
2
3
4
5
6
7
In __cxa_throw () ()
#4  0x0047d257 in std::uninitialized_copy<__gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator<int> > >, int*> (__first=..., __last=..., __result=0x0) at d:/coding/codeblocks/mingw/bin/../lib/gcc/mingw32/4.7.1/include/c++/bits/stl_uninitialized.h:119


d:\coding\codeblocks\mingw\lib\gcc\mingw32\4.7.1\include\c++\bits\stl_uninitialized.h:119:4257:beg:0x47d257
At d:\coding\codeblocks\mingw\lib\gcc\mingw32\4.7.1\include\c++\bits\stl_uninitialized.h:119
Last edited on
closed account (48T7M4Gy)
As a start adjust the value of N until the program runs. oops I see you've already done that.
Last edited on
These are all global in scope currently because this function simply "builds" the surface. The surface is drawn (over and over) in another function "DrawScene()" later. It made sense to me to have these vectors global so they never leave scope and have to be rebuilt.

So I take it you've never heard of passing by reference into your functions?

Have you compiled your code with debugging information enabled (-g)? By the way you need to back trace until you get into your code. The locations shown in the above code is in the stl code, which is probably not the root cause of the crash.

Does V1.clear() actually clear that vector from memory?

Yes, it clears the vector, however it may or may not change the capacity.

Is this implementation good?

I question the need for the two sets of loops and all the push_back() calls. You seem to know the size of the vectors so you would probably be better off sizing the vectors when you create them.

If a float is 4 bytes that means vecv_s and vecn_s will use more than 572 MB.
5001*5001*6*4 bytes ≈ 572 MB

If an int is 4 bytes that means vecf_s will use more than 381 MB.
5000*5000*4*4 ≈ 381 MB

It will actually be much more than that because a vector has some overhead. On a 64 bit compiler I expect it will be at least 24 bytes extra for storing a data pointer, the size and the capacity (other things like alignment might result in additional overhead). That gives at least an additional 572 MB.
5000*5000*24 ≈ 572 MB

572+381+572 MB ≈ 1.5 GB

If you increase N this number will grow quickly.
Last edited on

So I take it you've never heard of passing by reference into your functions?

A callback to the drawscene function is called multiple times a second. I don't think there is any better way to store the information other than a global variable, because every function goes in and out of scope multiple times. I'm open to better suggestions though.



Have you compiled your code with debugging information enabled (-g)? By the way you need to back trace until you get into your code. The locations shown in the above code is in the stl code, which is probably not the root cause of the crash.


I'm not sure how to do the traceback. I ran the debugger in code blocks from within the IDE which goes straight to the STL code. I'm sure there is an easy way to connect the dots back to my code, any guidance?

Not sure if I'm posting this in the right forum. Perhaps I need to find one with an emphasis on OpenGL and 3-D graphics. I'm likely not doing this in a wise manner. I have to imagine there is a better way to create a ton of polygons for the "ground". Any idea on who games like minecraft manage their memory with an "infinite" world? I can't even store a relatively small surface without taking up 1.5GB!!

If anyone has similar interests and could recommend resources/communities, I would appreciate that as well.
Umm... passing by reference is the way to go. If you're worried about speed, on my computer passing by reference is faster than calling globals.

For example: http://coliru.stacked-crooked.com/a/5c23dae8da91a2e0

But, anyway, the difference in speed is so little as to be negligible in all but the most performance-sensitive applications.


If you look at the stack trace (there should be a window in CodeBlocks showing the call stack) you should be able to find the bit of your code that called the STL code that did a bad_alloc.

Also, game like Minecraft 'chunk' the world; they don't actually render the whole world in one go. The idea is not to render anything you can't see; and, if that's still to far, add in a fog or something so that you can't see as far. That way you only need to render the surroundings, which could be in the order of 5,000 vertices, rather than the entire map.
Did you modify your project to add the debug information? If so then the problem line should have the cursor pointing to it in the editor window.

You should've also modified the project to increase your compiler warning levels.

Hey all. Thanks for the replies. The stack trace is kind of cryptic to me:

http://i.imgur.com/7TmXMJK.png


I did isolate the code that causes the error though. It's really simple code, but it takes forever to run and eventually errors out. It's the double loop in the code below:

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
#include <cmath>
#include <iostream>
#include <vector>
#include<stdlib.h>
using namespace std;


vector<vector<unsigned> > vecf;
vector<vector<int> > vecf_s;



using namespace std;

void SurfaceMesh(){
 int N = 5000;
 int k =0;
 float pi =  3.141592654;
 float xy_increment = .01;
 float x, y, z, nx, ny, nz;
 float freq = .1;

 float norm;
 int amp = 3;
 vector<int> V1;

  for(int i = 0; i<=N-1; i++){
        cout << "test " << V1.size() << ", " << vecf_s.size() << "\n";
    for(int j = 0; j<=N-1; j++){

        V1.push_back(j + i*(N+1));
        V1.push_back((int(i/(N+1))+1)*(N+1)+j + i*(N+1));
        V1.push_back((int(i/(N+1))+1)*(N+1)+j+1 + i*(N+1));
        V1.push_back(j+1 + i*(N+1));
        vecf_s.push_back(V1);
        V1.clear();
    }
  }
}

int main()
{
    SurfaceMesh();
    return 0;
}


I took out any custom classes, so anyone should be able to run this code fairly easily.
It works on my VS 2013 CE.
Output:
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
test 0, 23505000
test 0, 23510000
test 0, 23515000
test 0, 23520000
test 0, 23525000
test 0, 23530000
test 0, 23535000
test 0, 23540000
test 0, 23545000
test 0, 23550000
test 0, 23555000
test 0, 23560000
test 0, 23565000
test 0, 23570000
test 0, 23575000
test 0, 23580000
test 0, 23585000
test 0, 23590000
test 0, 23595000
test 0, 23600000
test 0, 23605000
test 0, 23610000
test 0, 23615000
test 0, 23620000
test 0, 23625000
test 0, 23630000
test 0, 23635000
test 0, 23640000
test 0, 23645000
test 0, 23650000
test 0, 23655000
test 0, 23660000
test 0, 23665000
test 0, 23670000
test 0, 23675000
test 0, 23680000
test 0, 23685000
test 0, 23690000
test 0, 23695000
test 0, 23700000
test 0, 23705000
test 0, 23710000
test 0, 23715000
test 0, 23720000
test 0, 23725000
test 0, 23730000
test 0, 23735000
test 0, 23740000
test 0, 23745000
test 0, 23750000
test 0, 23755000
test 0, 23760000
test 0, 23765000
test 0, 23770000
test 0, 23775000
test 0, 23780000
test 0, 23785000
test 0, 23790000
test 0, 23795000
test 0, 23800000
test 0, 23805000
test 0, 23810000
test 0, 23815000
test 0, 23820000
test 0, 23825000
test 0, 23830000
test 0, 23835000
test 0, 23840000
test 0, 23845000
test 0, 23850000
test 0, 23855000
test 0, 23860000
test 0, 23865000
test 0, 23870000
test 0, 23875000
test 0, 23880000
test 0, 23885000
test 0, 23890000
test 0, 23895000
test 0, 23900000
test 0, 23905000
test 0, 23910000
test 0, 23915000
test 0, 23920000
test 0, 23925000
test 0, 23930000
test 0, 23935000
test 0, 23940000
test 0, 23945000
test 0, 23950000
test 0, 23955000
test 0, 23960000
test 0, 23965000
test 0, 23970000
test 0, 23975000
test 0, 23980000
test 0, 23985000
test 0, 23990000
test 0, 23995000
test 0, 24000000
test 0, 24005000
test 0, 24010000
test 0, 24015000
test 0, 24020000
test 0, 24025000
test 0, 24030000
test 0, 24035000
test 0, 24040000
test 0, 24045000
test 0, 24050000
test 0, 24055000
test 0, 24060000
test 0, 24065000
test 0, 24070000
test 0, 24075000
test 0, 24080000
test 0, 24085000
test 0, 24090000
test 0, 24095000
test 0, 24100000
test 0, 24105000
test 0, 24110000
test 0, 24115000
test 0, 24120000
test 0, 24125000
test 0, 24130000
test 0, 24135000
test 0, 24140000
test 0, 24145000
test 0, 24150000
test 0, 24155000
test 0, 24160000
test 0, 24165000
test 0, 24170000
test 0, 24175000
test 0, 24180000
test 0, 24185000
test 0, 24190000
test 0, 24195000
test 0, 24200000
test 0, 24205000
test 0, 24210000
test 0, 24215000
test 0, 24220000
test 0, 24225000
test 0, 24230000
test 0, 24235000
test 0, 24240000
test 0, 24245000
test 0, 24250000
test 0, 24255000
test 0, 24260000
test 0, 24265000
test 0, 24270000
test 0, 24275000
test 0, 24280000
test 0, 24285000
test 0, 24290000
test 0, 24295000
test 0, 24300000
test 0, 24305000
test 0, 24310000
test 0, 24315000
test 0, 24320000
test 0, 24325000
test 0, 24330000
test 0, 24335000
test 0, 24340000
test 0, 24345000
test 0, 24350000
test 0, 24355000
test 0, 24360000
test 0, 24365000
test 0, 24370000
test 0, 24375000
test 0, 24380000
test 0, 24385000
test 0, 24390000
test 0, 24395000
test 0, 24400000
test 0, 24405000
test 0, 24410000
test 0, 24415000
test 0, 24420000
test 0, 24425000
test 0, 24430000
test 0, 24435000
test 0, 24440000
test 0, 24445000
test 0, 24450000
test 0, 24455000
test 0, 24460000
test 0, 24465000
test 0, 24470000
test 0, 24475000
test 0, 24480000
test 0, 24485000
test 0, 24490000
test 0, 24495000
test 0, 24500000
test 0, 24505000
test 0, 24510000
test 0, 24515000
test 0, 24520000
test 0, 24525000
test 0, 24530000
test 0, 24535000
test 0, 24540000
test 0, 24545000
test 0, 24550000
test 0, 24555000
test 0, 24560000
test 0, 24565000
test 0, 24570000
test 0, 24575000
test 0, 24580000
test 0, 24585000
test 0, 24590000
test 0, 24595000
test 0, 24600000
test 0, 24605000
test 0, 24610000
test 0, 24615000
test 0, 24620000
test 0, 24625000
test 0, 24630000
test 0, 24635000
test 0, 24640000
test 0, 24645000
test 0, 24650000
test 0, 24655000
test 0, 24660000
test 0, 24665000
test 0, 24670000
test 0, 24675000
test 0, 24680000
test 0, 24685000
test 0, 24690000
test 0, 24695000
test 0, 24700000
test 0, 24705000
test 0, 24710000
test 0, 24715000
test 0, 24720000
test 0, 24725000
test 0, 24730000
test 0, 24735000
test 0, 24740000
test 0, 24745000
test 0, 24750000
test 0, 24755000
test 0, 24760000
test 0, 24765000
test 0, 24770000
test 0, 24775000
test 0, 24780000
test 0, 24785000
test 0, 24790000
test 0, 24795000
test 0, 24800000
test 0, 24805000
test 0, 24810000
test 0, 24815000
test 0, 24820000
test 0, 24825000
test 0, 24830000
test 0, 24835000
test 0, 24840000
test 0, 24845000
test 0, 24850000
test 0, 24855000
test 0, 24860000
test 0, 24865000
test 0, 24870000
test 0, 24875000
test 0, 24880000
test 0, 24885000
test 0, 24890000
test 0, 24895000
test 0, 24900000
test 0, 24905000
test 0, 24910000
test 0, 24915000
test 0, 24920000
test 0, 24925000
test 0, 24930000
test 0, 24935000
test 0, 24940000
test 0, 24945000
test 0, 24950000
test 0, 24955000
test 0, 24960000
test 0, 24965000
test 0, 24970000
test 0, 24975000
test 0, 24980000
test 0, 24985000
test 0, 24990000
test 0, 24995000
Press any key to continue . . .
Touche... It does work. It only breaks when I add the additional two vectors (which are unfortunately custom classes) The full code is shown below.

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
#include <cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include<stdlib.h>
#include "Vector3f.h"
using namespace std;

// This is the list of points (3D vectors)
vector<Vector3f> vecv_s;
// This is the list of normals (also 3D vectors)
vector<Vector3f> vecn_s;

// This is the list of faces (indices into vecv and vecn)
vector<vector<unsigned> > vecf;
vector<vector<int> > vecf_s;



void SurfaceMesh(){
 int N = 5000;
 int k =0;
 float pi =  3.141592654;
 float xy_increment = .01;
 float x, y, z, nx, ny, nz;
 float freq = .1;

 float norm;
 int amp = 3;
 vector<int> V1;

 for(int i = 0; i<=N; i++){
    for(int j = 0; j<=N; j++){

        x = i*xy_increment-(N+1)/2 *xy_increment;
        y = j*xy_increment-(N+1)/2 *xy_increment;
        z = amp*sinf(freq*x)+amp*sinf(freq*y);

        //Tx = dz/dx
        //Ty = dz/dy
        //N = Tx X Ty
        // N_vec = (-amp*freq*cos(freq*x),   -amp*freq*cos(freq*y),  1)
        // Normalize
        nx= -amp*freq*cos(freq*x);
        ny= -amp*freq*cos(freq*x);
        nz= 1;
        norm = sqrt(nx*nx + ny*ny + nz*nz);
        nx = nx/norm;
        ny = ny/norm;
        nz = nz/norm;

      // ADDING THESE TWO VECTORS CRASHES THE PROGRAM
        vecv_s.push_back(Vector3f(x,y,z));
        vecn_s.push_back(Vector3f(nx,ny,nz));
      // ADDING THESE TWO VECTORS CRASHES THE PROGRAM

    }

 }
  for(int i = 0; i<=N-1; i++){
        cout << "test " << V1.size() << ", " << vecf_s.size() << ", " << vecv_s.size() << ", " << vecn_s.size() << "\n";
    for(int j = 0; j<=N-1; j++){

        V1.push_back(j + i*(N+1));
        V1.push_back((int(i/(N+1))+1)*(N+1)+j + i*(N+1));
        V1.push_back((int(i/(N+1))+1)*(N+1)+j+1 + i*(N+1));
        V1.push_back(j+1 + i*(N+1));
        vecf_s.push_back(V1);
        V1.clear();

    }
  }

}



// Main routine.
// Set up OpenGL, define the callbacks and start the main loop
int main( int argc, char** argv )
{

        SurfaceMesh();

    return 0;	
}



The vector classes can be found at the following location under "Assignment 0 starter code" if you wish to run it:

http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-837-computer-graphics-fall-2012/assignments/

The vectors are only about 25mb each. Any advice is appreciated. I'm still not clear on the stack trace debugging, you can see from my previous post what comes out of that.

What operating system are you using? 32 or 64 bit? What compiler/version are you using?

How much memory does your system have?

What is the size of an int on your system?

Remember you are trying to build, in this "simple" function a vector of 5,000 * 5,000 vectors of 4 integer values. So you have at minimum 25,000,000 * (4 * 4) bytes, or 400,000,000 bytes at a minimum. This doesn't even consider any overhead being used by the vector class.

Your calculations seem a little strange as well. You seem to be forgetting that integer math has no fractions. Look at your second calculation:
V1.push_back((int(i/(N+1))+1)*(N+1)+j + i*(N+1));
Until i is larger than N + 1 that first calculation i / (N + 1) yields zero because both of the operands are integers. I also don't understand why you're casting an integer calculation to an integer.

The stack trace is kind of cryptic to me:

The trace you've shown is in the standard library routines, but the actual problem is being caused by your code so you need to backtrace farther until you enter your code to see where the problem is actually located. I would guess that you're running out of memory trying to reallocate memory for that vector.

but it takes forever to run and eventually errors out.

It's taking forever to run because of all the memory reallocation required during the loop. You may want to think about either reserving memory for the vector before the loop, or size the vector properly when you declare the vector to avoid the relocations.

Does V1 really need to be a vector?

I changed V1 from a vector to a simple struct since it only has four values.
Using N=1000, your unmodified code ran 17.215 seconds on my machine.
Using a struct for V1, it ran in 0.374 seconds.

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
#include <cmath>
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <ctime>
using namespace std;

struct V1
{   int first; 
    int second; 
    int third; 
    int forth;
};
vector<V1> vecf_s;

    
void SurfaceMesh()
{   int N = 1000;
    int k =0;
    float pi =  3.141592654;
    float xy_increment = .01;
    float x, y, z, nx, ny, nz;
    float freq = .1;

    float norm;
    int amp = 3;
    V1 v1;
        
    vecf_s.reserve (N*N);
    for(int i = 0; i<=N-1; i++)
    {   //  cout << "test " << V1.size() << ", " << vecf_s.size() << "\n";
        for(int j = 0; j<=N-1; j++)
        {   v1.first = j + i*(N+1);
            v1.second = ((i/(N+1))+1)*(N+1)+j + i*(N+1);
            v1.third = ((i/(N+1))+1)*(N+1)+j+1 + i*(N+1);
            v1.forth = j+1 + i*(N+1);
            vecf_s.push_back(v1);
        }
    }
}

int main()
{   clock_t     t;
    double      elapsed;
    
    t = clock();
    SurfaceMesh();
    t = clock() - t;
    elapsed = (double)t / CLOCKS_PER_SEC;
    cout << "Elapsed sec = " << elapsed << endl;
    system ("pause");
    return 0;
}


What operating system are you using? 32 or 64 bit? What compiler/version are you using?

Win10 64 bit

How much memory does your system have?


16 gb


What is the size of an int on your system?


4 bytes



Your calculations seem a little strange as well. You seem to be forgetting that integer math has no fractions. Look at your second calculation:
V1.push_back((int(i/(N+1))+1)*(N+1)+j + i*(N+1));
Until i is larger than N + 1 that first calculation i / (N + 1) yields zero because both of the operands are integers. I also don't understand why you're casting an integer calculation to an integer.


I'm positive there is a better way to do it. The point is that at the end of the outer loop, the indexing needs to bump up by a factor of (N+1). I used "int()" as a clever (not so clever..??) way of rounding. Maybe floor() works just as well? I don't know I was NOT in the zone the day I wrote that code. I was just trying to get the damn surface to render.... It worked (for small N)!


The trace you've shown is in the standard library routines, but the actual problem is being caused by your code so you need to backtrace farther until you enter your code to see where the problem is actually located. I would guess that you're running out of memory trying to reallocate memory for that vector.



Yes I can see that, I'm sure there is a way to make the IDE tell you which line of code is calling that particular library function, but I'm just not sure how. The higher level codes I'm used to give you the trace from failure point all the way up to the written script. I'm sure codeblocks will do the same thing, I'm just not sure how to get it to do that.




It's taking forever to run because of all the memory reallocation required during the loop. You may want to think about either reserving memory for the vector before the loop, or size the vector properly when you declare the vector to avoid the relocations.


Previously I used a similar architecture to read an object file. It made more sense to dynamically allocate memory using vector.push() rather than declaring the size upfront, because I didn't know how many vertices the object file had without calculating it apriori. Calculating it apriori seemed to be wasteful, because it required a loop just to count the number of elements and nothing else.

In this application, however, you're correct.. I can do a simple calculation to determine the size necessary. This would increase performance, but not memory allocation issues I believe, no?

I'm also interested in Abstraction's recommendation of using structs. Is this method so much faster because V1 no longer is dyanmically allocating memory (which I understand is a lot of overhead). This code needs to be severely optimized, but I'm just beginning to understand the lay-of-the land when it comes to 3d graphics. This optimization will get runtime down to a fraction of what it currently is, but I don't think it is going to fix any out-of-memory errors.

I have to imagine games like Crysis and other high-detail games are rendering many more polygons than I am trying to, no? Plus they are doing a lot more complex physics, lighting, texturing etc... I'm going to have to do some more research it seems to figure out how to do this more efficiently!!
Last edited on
It still works for me, but only on a 64bit build. On a 32bit build I got a bad_alloc exception.
Thanks for running it Thomas. That is interesting. Anyone know why it might work for one and not the other?
On a 32bit build only 4GB are usable and this might not be enough.
http://stackoverflow.com/questions/8869563/how-much-memory-can-be-accessed-by-a-32-bit-machine
Topic archived. No new replies allowed.