C++ Speicherbeadrf nimmt kontinuierlich zu.
-
Hallo Leute.
Ich schreibe im Moment ein Programm mit Qt und C++.
Ich habe zusätzlich Opengl eingebunden.
Ich habe ein Array mit 500 Punkten (mit x, y, z -Koordinaten) und diese sollen einfach gezeichnet werden.
Das funktioniert alles.Aber:
Abhängig von der Größe das Arrays nimmt der Speicherbedarf meines Programms kontinuierlich zu bis die Framerate von Opengl völlig einbrich.Ich bin Newbie in der C++-Programmierung und komme von Java.
Ich denke mal das das eine ganz Grundlegende Sache ist, die ich falsch gemacht habe.Danke
-
Wie legst du denn das Array an? Je nach dem wie du es anlegst, wirst du dich evtl. darum kümmern müssen, es wieder frei zugeben. Es gibt aber mehrere Möglichkeiten die Speicherplatzfreigabe zu automatisieren.
Wie instanzierst du denn deine Objekte?
-
Gast# schrieb:
HIch bin Newbie in der C++-Programmierung und komme von Java.
Ich denke mal das das eine ganz Grundlegende Sache ist, die ich falsch gemacht habe.Das denke ich auch. Die größte Umstellung dürfte die sein, dass mit new angeforderter Speicher in C++ nicht automatisch freigegeben wird, wenn er nicht mehr gebraucht wird.
Wenn du genauere Hilfe brauchst, musst du den Code zeigen.
-
******Hier die Deklaration:
Individuum Population[POPSIZE];Individuum ist eine Klasse, die x,y,z-Koordinaten und r,g,b-Werte für die Farben enthält.
****Hier die Methode, in der ich die Werte der Array-Elemente initialisiere:
void OglCode::makePop(){ for(int i = 0; i < POPSIZE; i++){ randx = (double)rand()/(double)RAND_MAX; randz = (double)rand()/(double)RAND_MAX; randy = (double)rand()/(double)RAND_MAX; Population[i].ID = i; Population[i].r0 =(float)abs(randx); Population[i].g0 =(float)abs(randy); Population[i].b0 =(float)abs(randz); Population[i].r = Population[i].r0; Population[i].g = Population[i].g0; Population[i].b = Population[i].b0; Population[i].x = (float)randx-0.5; Population[i].y = (float)randy-0.5; Population[i].z = (float)randz-0.5; } }
-
Ok hier nochmal der komplette code:
#include "math.h" #include "time.h" #include "OglCode.h" #if defined(Q_CC_MSVC) #pragma warning(disable:4305) // init: truncation from const double to float #endif int const POPSIZE = 10; float spread = 1; float quadSize = 0.02f; int sphereResX = 4; int sphereResY = 4; float sphereSize = 0.02; GLUquadricObj* qobj = gluNewQuadric() ; int first; int first_temp; Individuum Population[POPSIZE]; double randx; double randy; double randz; int mode = GL_RENDER; int Listcount = 0; float g_LightPosition[4] = {9, 5, 0, 1}; float g_LightDiffuse[4] = {0.77f,0.0f,0.89f,1.0f}; float g_LightAmbient[4] = {0.0f,0.0f,0.0f,0.0f}; float g1_LightPosition[4] = {-9, 20, -10, 1}; float g1_LightDiffuse[4] = {0.0f,0.77f,1.0f,1.0f}; float g1_LightAmbient[4] = {0.0f,0.0f,0.0f,0.0f}; float g_bLight = true; UINT g_Texture[MAX_TEXTURES] = {0}; // This holds the texture info, referenced by an ID int g_ViewMode = GL_TRIANGLES; // We want the default drawing mode to be normal bool g_bLighting = false; // Turn lighting on initially float g_RotateX = 0.0f; // This is the current value at which the model is rotated float g_RotateY = 0.0f; float g_RotateZ = 0.0f; float g_RotationSpeed = 1.0f; // This is the speed that our model rotates. (-speed rotates left) float distanz = -2.0f; static int timer_interval = 10; // timer interval (millisec) /*! Create a OglCode widget */ OglCode::OglCode( QWidget* parent, const char* name, const QGLWidget* shareWidget ) : QGLWidget( parent, name, shareWidget ) { startTimer( timer_interval ); xRot = yRot = zRot = 0.0; // default object rotation scale = 1.5; // default object scale } OglCode::OglCode( const QGLFormat& format, QWidget* parent, const char* name, const QGLWidget* shareWidget ) : QGLWidget( format, parent, name, shareWidget ) { startTimer( timer_interval ); xRot = yRot = zRot = 0.0; // default object rotation scale = 1.5; // default object scale } OglCode::~OglCode() { } void OglCode::timerEvent(QTimerEvent*) { updateGL(); } void OglCode::initializeGL() { makePop(); srand((unsigned)time(0)); glEnable( GL_DEPTH_TEST ); glEnable(GL_LIGHT0); // Turn on a light with defaults set glDisable(GL_LIGHTING); // Turn on lighting glEnable(GL_COLOR_MATERIAL); // Allow color } void OglCode::resizeGL( int w, int h ) { glViewport( 0, 0, (GLint)w, (GLint)h ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0); } void OglCode::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer glLoadIdentity(); // Reset The matrix glShadeModel (GL_SMOOTH); //////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** //////////////////// glLightfv( GL_LIGHT0, GL_POSITION, g_LightPosition ); glLightfv( GL_LIGHT0, GL_DIFFUSE, g_LightDiffuse ); glLightfv( GL_LIGHT0, GL_AMBIENT, g_LightAmbient ); glLightfv( GL_LIGHT1, GL_POSITION, g1_LightPosition ); glLightfv( GL_LIGHT1, GL_DIFFUSE, g1_LightDiffuse ); glLightfv( GL_LIGHT1, GL_AMBIENT, g1_LightAmbient ); // Give OpenGL our position, then view, then up vector //gluLookAt( 0,0, distanz, 0, 0, 0, 0, 1, 0); // We want the model to rotate around the axis so we give it a rotation // value, then increase/decrease it. You can rotate right of left with the arrow keys. glRotatef(g_RotateX, 0, 1.0f, 0); // Rotate the object around the Y-Axis g_RotateX += g_RotationSpeed; // Increase the speed of rotation drawCoordinateGizmo(); drawGrid(); for(int i = 0; i< POPSIZE;i++){ glPushMatrix(); glTranslatef(Population[i].x,Population[i].y,Population[i].z); glColor3f(Population[i].r,Population[i].g,Population[i].b); gluSphere(gluNewQuadric(),sphereSize,sphereResX,sphereResY); glPopMatrix(); } } void OglCode::drawGrid(){ glLineWidth(2.0); glColor3f(1.0,1.0,1.0); glBegin(GL_LINES); glVertex3f(-0.5,0,0.5); glVertex3f(-0.5,0,-0.5); glVertex3f(-0.4,0,0.5); glVertex3f(-0.4,0,-0.5); glVertex3f(-0.3,0,0.5); glVertex3f(-0.3,0,-0.5); glVertex3f(-0.2,0,0.5); glVertex3f(-0.2,0,-0.5); glVertex3f(-0.1,0,0.5); glVertex3f(-0.1,0,-0.5); glVertex3f(0,0,0.5); glVertex3f(0,0,-0.5); glVertex3f(0.1,0,0.5); glVertex3f(0.1,0,-0.5); glVertex3f(0.2,0,0.5); glVertex3f(0.2,0,-0.5); glVertex3f(0.3,0,0.5); glVertex3f(0.3,0,-0.5); glVertex3f(0.4,0,0.5); glVertex3f(0.4,0,-0.5); glVertex3f(0.5,0,0.5); glVertex3f(0.5,0,-0.5); //////////////////////////////////////////// glVertex3f(-0.5,0,-0.5); glVertex3f(0.5,0,-0.5); glVertex3f(-0.5,0,-0.4); glVertex3f(0.5,0,-0.4); glVertex3f(-0.5,0,-0.3); glVertex3f(0.5,0,-0.3); glVertex3f(-0.5,0,-0.2); glVertex3f(0.5,0,-0.2); glVertex3f(-0.5,0,-0.1); glVertex3f(0.5,0,-0.1); glVertex3f(-0.5,0,0); glVertex3f(0.5,0,0); glVertex3f(-0.5,0,0.1); glVertex3f(0.5,0,0.1); glVertex3f(-0.5,0,0.2); glVertex3f(0.5,0,0.2); glVertex3f(-0.5,0,0.3); glVertex3f(0.5,0,0.3); glVertex3f(-0.5,0,0.4); glVertex3f(0.5,0,0.4); glVertex3f(-0.5,0,0.5); glVertex3f(0.5,0,0.5); glEnd(); } void OglCode::drawCoordinateGizmo(){ glLineWidth(3.0); glBegin(GL_LINES); glColor3f(1,0,0); glVertex3d(0.5,0,0); glVertex3d(0,0,0); glEnd(); glBegin(GL_LINES); glColor3f(0,1,0); glVertex3d(0,0.5,0); glVertex3d(0,0,0); glEnd(); glBegin(GL_LINES); glColor3f(0,0,1); glVertex3d(0,0,0.5); glVertex3d(0,0,0); glEnd(); } void OglCode::makePop(){ for(int i = 0; i < POPSIZE; i++){ randx = (double)rand()/(double)RAND_MAX; // randy = Math.random()*spread; // randy = -Math.sqrt(Math.pow(randx,2)); randz = (double)rand()/(double)RAND_MAX; randy = (double)rand()/(double)RAND_MAX; //Population[i] = new Individuum(); Population[i].ID = i; Population[i].r0 =(float)abs(randx); Population[i].g0 =(float)abs(randy); Population[i].b0 =(float)abs(randz); /* Population[i].r0 =1; Population[i].g0 =1; Population[i].b0 =1;*/ Population[i].r = Population[i].r0; Population[i].g = Population[i].g0; Population[i].b = Population[i].b0; Population[i].x = (float)randx-0.5; Population[i].y = (float)randy-0.5; Population[i].z = (float)randz-0.5; } } void OglCode::drawIndSphere(Individuum ind){ glPushMatrix(); glTranslatef(ind.x,ind.y,ind.z); glColor3f(ind.r,ind.g,ind.b); gluSphere(qobj,sphereSize,sphereResX,sphereResY); glPopMatrix(); } void OglCode::mousePressEvent( QMouseEvent *e ) { if ( e->button() == QMouseEvent::LeftButton ) { //The original glut had a state of the button (up or down) call //here we just say if the button does anything, spin. //if (e->type() == QMouseEvent::MouseButtonPress) { g_RotationSpeed++; } } if ( e->button() == QMouseEvent::RightButton) { //The original glut had a state of the button (up or down) call //here we just say if the button does anything, spin. //if (e->type() == QMouseEvent::MouseButtonPress) { g_RotationSpeed--; } } }
-
Komplett ist der nicht, da man das so nicht zum Laufen bekommt. Du könntest aber einen Memory Leak Checker wie zum Beispiel valgrind dafür benutzen.
Einfach mit valgrind --num-callers=32 --leak-check=yes programmname starten, ein paar Sekunden laufen lassen und dann siehst du im report, welcher Speicher am Ende nicht wieder freigegeben wurde.
-
Das es bei dir nicht läuft, liegt daran, dass ich dir einige klassen vorenthalten habe. ich glaube es wäre zu viel , wenn ich die auch noch posten würde, oder ?
Habe ich das denn mit der Array-Deklaration richtig gemacht...
Das Array brauche ich überigens das ganze Programm über. Also reichts das doch wenn der reservierte Speicher beim Schließen des Programms automatisch freigegeben wird, oder ?
Aber danke Jungs und vieleicht sogar Mädels.
-
Du machst da gluNewQuadric, gibst du diese Objekte auch wieder irgendwo frei? Sollte man nämlich tun. Wenn du in jedem Durchlauf neue anlegst ohne die alten zu löschen, könnte der Speicherverbrauch auch daher rühren
-
Ich glaube du hast Recht.
Aber wie gibt man diese Objekte denn wieder frei geben.
Wie erwähnt, komme ich ja aus dem Java-Bereich und da gibt es ja den Garbage Collector.....Aber danke....
Werde in der Zwischenzeit mal im Netz nachschauen wie man dieses Problem lösen kann.
-
Du hattest Recht ....
Habe das Objekt zwar nicht freigegeben aber einfach immer das selbe gluQuadric verwendet und nicht jedesmal gluNewQuadric aufgerufen.
DANKE

-
wer is Ponto? ^^
void gluDeleteQuadric(GLUquadricObj *state);Damit gibst du ein Quadric wieder frei. Dazu musst du dir natürlich auch nen Zeiger anlegen, wo die Adresse drinne steht.
Das hat in diesem Fall aber nix mit C++ direkt zu tun, sondern halt mit der glu-Bibliothek.
-
Who the **** is Ponto ??
Ich meinte natürlich dich...

Dieses Wetter und mein Heuschnupfen machen mich heute noch verwirrter als ich es sowieso schon bin....
Aber danke für eure Hilfe.....