hi everybody!

I really need your help here. I am developing a 3D game. so far I have came no further than finishing the 3D engine and print out some basic 3D-models.

everything works okay, with exception of a bug, occuring after a couple of minutes of running time. it starts with that everything freezes, and then either I have to use process manager to shut it down, or it goes back to working but this time much slower, and after a couple of second giving the error

Microsoft Visual C++ Runtime Library
Runtime Error
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information

I have done several tests with different objects. my models are drawn with only triangles. when I draw a cube in the 3D-world it doesn't occur from what I've seen. when I drawn a floor with 512 triangles the bug came after not even a half minute. when I draw a 3D-creature into the world, it take a few minutes before the bug come.

I'll show you the codes below. in this code the 3D-creature is drawn in the 3D-world.

defines.h

#ifndef DEFINES_H
#define DEFINES_H


#define PI 3.14159265359

#define VK_a 0x41
#define VK_d 0x44
#define VK_s 0x57
#define VK_w 0x53
#define FADE 1.02


#define ANGLE_V 0.01
#define MOVE_V 0.01
#define SORTBASE 2


int w=800;
double SCREEN_M = 1.7;
int h=(int)(w/SCREEN_M);
int angleRangeX = 90;
int angleRangeY = (int)(angleRangeX/SCREEN_M);

int maxARX = 180;
int maxARY = 180;


double sX = 2.0f/angleRangeX;
double sY = 2.0f/angleRangeY;


#endif

engine.h

#ifndef ENGINE_H
#define ENGINE_H

#include <gl/gl.h>
#include <cmath>
#include <vector>
#include <iostream> 
#include <stdlib.h> 
#include <fstream>
#include "defines.h"

using namespace std;

class Point3D{
      public:
             double x,y,z;
             double color[3];
             Point3D(double x, double y, double z){
                            this->x = x;
                            this->y = y;
                            this->z = z;
                            color[0] = 1.0;
                            color[1] = 1.0;
                            color[2] = 1.0;
             }

};

double getAngleX(Point3D* point1, Point3D* point2){
       double deltax = point2->x - point1->x;
       double deltaz = point2->z - point1->z;

       double angle = atan2(deltaz, deltax)*180/PI;
       return angle-90;
}

double getAngleY(Point3D* point1, Point3D* point2){
       double deltay = point2->y - point1->y;
       double deltaz = point2->z - point1->z;

       double angle = atan2(deltay, deltaz)*180/PI;
       return angle;
}

double dis(Point3D* point1, Point3D* point2){
       return sqrt(
              pow(point2->x-point1->x, 2)+
              pow(point2->y-point1->y, 2)+
              pow(point2->z-point1->z, 2)

       );
}

void Rotate(Point3D* rotatingPoint, Point3D* centerPoint, double aX, double aY){
     double deltax = rotatingPoint->x - centerPoint->x;
     double deltay = rotatingPoint->y - centerPoint->y;
     double deltaz = rotatingPoint->z - centerPoint->z;


     double angleX = getAngleX(centerPoint, rotatingPoint)+aX+90;
     double disXZ = sqrt(pow(deltax,2)+pow(deltaz,2));
     double radX = angleX*PI/180;

     rotatingPoint->z = centerPoint->z + disXZ*sin(radX);
     rotatingPoint->x = centerPoint->x + disXZ*cos(radX);

     double angleY = getAngleY(centerPoint, rotatingPoint)+aY;
     deltay = rotatingPoint->y - centerPoint->y;
     deltaz = rotatingPoint->z - centerPoint->z;
     double disZY = sqrt(pow(deltaz,2)+pow(deltay,2));
     double radY = angleY*PI/180;

     rotatingPoint->y = centerPoint->y + disZY*sin(radY);
     rotatingPoint->z = centerPoint->z + disZY*cos(radY);
}


class Triangle{
      public:
             Point3D* point[3];
             float color[3];
             Triangle(Point3D* point[3], float color[3]){
                               this->point[0] = point[0];
                               this->point[1] = point[1];
                               this->point[2] = point[2];
                               this->color[0] = color[0];
                               this->color[1] = color[1];
                               this->color[2] = color[2];


                               for(int i=0; i<3;i++){
                                   this->point[i]->color[0] = color[0];
                                   this->point[i]->color[1] = color[1];
                                   this->point[i]->color[2] = color[2];
                               }

             }

             Triangle(){}

             Point3D* Center(){
                      Point3D* p = new Point3D(
                               (point[0]->x+point[1]->x+point[2]->x)/3,
                               (point[0]->y+point[1]->y+point[2]->y)/3,
                               (point[0]->z+point[1]->z+point[2]->z)/3
                      );
             }
};

Triangle* clone(Triangle* triangle){
          Point3D* point[3];
          for (int i=0; i<3;i++){
              point[i] = new Point3D(triangle->point[i]->x,triangle->point[i]->y,triangle->point[i]->z);
          }
          return new Triangle(point, triangle->color);
}

bool trianglesSorted(vector<Triangle*>* triangles){
     for (int i=1; i<triangles->size(); i++){
         if (triangles->at(i-1)->Center()->z < triangles->at(i)->Center()->z){
                                   return false;
         }
     }
     return true;
}

void sortTriangles(Triangle* triangles[], int size){
     for (int i=0; i<size; i++){
         for (int j=size-1; j>i; j--){
             if (triangles[j]->Center()->z > triangles[i]->Center()->z){
                                           Triangle* holder = clone(triangles[i]);
                                           triangles[i] = triangles[j];
                                           triangles[j] = holder;
             }
         }
     }              
}

void ViewTriangle3D(Point3D* view, Triangle* triangle){

     bool isInView = true;
     double maxX=0,maxY=angleRangeX/2,minX=0,minY=angleRangeY/2;
     float c[3][2];

     double a = getAngleX(view, triangle->Center());


     bool isNotBehind = true;
     double cd = sqrt(pow(view->x-triangle->Center()->x, 2)+
            pow(view->y-triangle->Center()->y, 2)+
            pow(view->z-triangle->Center()->z, 2)
     );

     for (int i=0; i<3; i++){
         double aX = getAngleX(view, triangle->point[i]);
         double aY = getAngleY(view, triangle->point[i]);

         if (aX < -maxARX/2 || aX > maxARX / 2 || aY < -maxARY/2 || aY > maxARY/2){
                                   isNotBehind = false;
         }

         double d = sqrt(pow(view->x-triangle->point[i]->x, 2)+
         pow(view->y-triangle->point[i]->y, 2)+
         pow(view->z-triangle->point[i]->z, 2)
         );


         if (isNotBehind){
                          int b = i-1;
                          if (b < 0){b = 2;}
                          for (int col=0; col<3;col++){

                              double diff = pow(FADE, d);
                              triangle->point[i]->color[col] = triangle->color[col];
                              triangle->point[i]->color[col] /= diff;

                          }
         }

         double bx = sX, by=sY;

         float x = aX*bx;
         float y = aY*by;
         c[i][0] = x;
         c[i][1] = y;

     }


     if (isNotBehind){
        for (int i=0; i<3;i++){
            glColor3f(triangle->point[i]->color[0], triangle->point[i]->color[1], triangle->point[i]->color[2]);
            glVertex2f(c[i][0],c[i][1]);
        }
     }

}


class Camera{
      public:
             Point3D* position;
             double angleX, angleY;

             Camera(Point3D* position, double angleX, double angleY){
                             this->position = position;
                             this->angleX = angleX;
                             this->angleY = angleY;
             }

             void Move(double distance, double aX){
                  position->x += distance*cos(-(angleX+90+aX)*PI/180);
                  position->z += distance*sin(-(angleX+90+aX)*PI/180);
             }
};



class World{
      public:
             vector<Triangle*>* faces;
             World(){
                     faces = new vector<Triangle*>();
             }

             void addFace(Point3D* p1, Point3D* p2, Point3D* p3, float r, float g, float b){
                  Triangle* triangle = new Triangle();
                  triangle->point[0] = p1;
                  triangle->point[1] = p2;
                  triangle->point[2] = p3;
                  triangle->color[0] = r;
                  triangle->color[1] = g;
                  triangle->color[2] = b;

                  faces->push_back(triangle);

             }

             void view(Camera* camera){
                  Point3D* inv = new Point3D(
                                   -camera->position->x,
                                   -camera->position->y,
                                   -camera->position->z

                          );
                  Triangle* t[faces->size()];
                  for (int i=0; i<faces->size(); i++){
                      t[i] = clone(faces->at(i));
                      for (int p=0; p<3; p++){
                          Rotate(t[i]->point[p], camera->position, camera->angleX, camera->angleY);
                      }

                  }

                  sortTriangles(t, faces->size());

                  for (int i=0; i<faces->size(); i++){
                      ViewTriangle3D(camera->position, t[i]);
                  }
             }

};


class Model{
      public:
             vector<Triangle*>* faces;
             vector<Triangle*>* copy;
             World* world;
             Point3D* pos;
             double angleX, angleY;
             Model(Point3D* pos, World* world){
                            this->pos = pos;
                            this->faces = new vector<Triangle*>();
                            this->copy = new vector<Triangle*>();
                            this->world = world;
                            angleX = 0;
                            angleY = 0;
             }

             void addFace(Point3D* p1, Point3D* p2, Point3D* p3, float r, float g, float b){
                  Triangle* triangle = new Triangle();
                  triangle->point[0] = p1;
                  triangle->point[1] = p2;
                  triangle->point[2] = p3;
                  triangle->color[0] = r;
                  triangle->color[1] = g;
                  triangle->color[2] = b;

                  faces->push_back(triangle);
                  Triangle* cop = clone(triangle);
                  for (int i=0; i<3;i++){
                      cop->point[i]->x = triangle->point[i]->x + pos->x;
                      cop->point[i]->y = triangle->point[i]->y + pos->y;
                      cop->point[i]->z = triangle->point[i]->z + pos->z;
                  }
                  this->copy->push_back(cop);
                  this->world->faces->push_back(cop);

             }

             void update(){
                  for (int i=0; i<faces->size(); i++){
                      Triangle* v = copy->at(i);
                      Triangle* lv = faces->at(i);
                      for (int p=0; p<3; p++){
                          Point3D* npoint = new Point3D(lv->point[p]->x,lv->point[p]->y,lv->point[p]->z);
                          Rotate(npoint, new Point3D(0,0,0), angleX, angleY);
                          npoint->x += pos->x;
                          npoint->y += pos->y;
                          npoint->z += pos->z;

                          v->point[p] = npoint;
                      }
                  }
             }
};

Model* clone(Model* model){
       Model* n = new Model(new Point3D(model->pos->x,model->pos->y,model->pos->z), model->world);
       for (int i=0; i<model->faces->size();i++){
           Triangle* tri = model->faces->at(i);
           n->addFace(tri->point[0], tri->point[1], tri->point[2], tri->color[0], tri->color[1], tri->color[2]);
       }
       return n;
}


Point3D* parsePoint(int color){
         Point3D* point = new Point3D(0,0,0);

         point->x = (int)(color/pow(256.0, 2.0));
         color-=(int) (point->x*pow(256.0,2.0));
         point->y = (int)(color/pow(256.0, 1.0));
         color-=(int) (point->y*pow(256.0,1.0));
         point->z = color;


         return point;
}



#endif

gameworld.h

#ifndef GAMEWORLD_H
#define GAMEWORLD_H

#include "engine.h"

double b = 0.0;

class Controller{
      public:
             double speed, *angleX, *angleY, dx,dy, score;
             Point3D* pos;

             Controller(Camera* camera){
                                pos = camera->position;
                                speed = 0;
                                angleX = &camera->angleX;
                                angleY = &camera->angleY;
                                dx = 0;
                                dy = 0;
                                score = 0;
             }
             Controller(Model* model){
                                pos = model->pos;
                                speed = 0;
                                angleX = &model->angleX;
                                angleY = &model->angleY;
                                dx = 0;
                                dy = 0;
                                score = 0;
             }

             Controller(){
                          speed = 0;
                          dx = 0;
                          dy = 0;
                          score = 0;
             }

             void update(){
                  pos->x += speed*cos(-(*angleX-90)*PI/180);
                  pos->z += speed*sin(-(*angleX-90)*PI/180);
                  pos->y += -speed*sin((*angleY)*PI/180);
                  *angleX+=dx;
                  *angleY+=dy;

                  while (*angleX >= 360){
                        *angleX-=360;
                  }
                  while (*angleX < 0){
                        *angleX+=360;
                  }
                  while (*angleY >= 360){
                        *angleY-=360;
                  }
                  while (*angleY < 0){
                        *angleY+=360;
                  }


             }

};


template <class parent> class Creature{
      public:
             parent* game;
             Controller* ctrlr;
             Model* model;
             void (*draw)(Controller*, Model*);
             void (*main)(Controller*, parent*);

             Creature(void (*draw)(Controller*, Model*), void (*main)(Controller*, parent*), parent* g){
                           this->draw = draw;
                           this->game = g;
                           model = new Model(g->getSpawnPoint(), g->world);
                           ctrlr = new Controller(model);
                           (*draw)(ctrlr, model);
             }

};


template <class parent> class Player{
         public:
                parent* game;
                Controller* ctrlr;
                bool active;

                Player(parent* g){
                               game = g;
                               ctrlr = new Controller(g->camera);
                               active = true;
                }


};


double random(){
    double i = 0.34872894789;
    b+=i;
    if (b>1){i--;}
    return b;
}


class Game{
      public:
             Player<Game>* player;
             Camera* camera;
             World* world;

             vector<Creature<Game>*>* creatures;
             Game(){
                    camera = new Camera(new Point3D(0,0,0),0,0);
                    player = new Player<Game>(this);
                    world = new World();
             }
             Point3D* getSpawnPoint(){
                      Point3D* newPoint = new Point3D(0,0,0);
                      double dis = 16*12 + 16*6*random();
             }

             void AddCreature(Creature<Game>* (*specie)(Game*)){
                  Point3D* pos = getSpawnPoint();
                  Creature<Game>* creature = (*specie)(this);
                  creatures->push_back(creature);
             }

             void update(){
                  world->view(camera);
             }
};



//speedo Mob


void speedoM(Controller* selfctrlr, Model* model){
     Point3D* f= new Point3D(0,0,8);
     Point3D* ul=new Point3D(-8,8,0);
     Point3D* ur=new Point3D(8,8,0);
     Point3D* ml=new Point3D(-8,0,0);
     Point3D* mr=new Point3D(8,0,0);
     Point3D* bl=new Point3D(-8,-8,0);
     Point3D* br=new Point3D(8,-8,0);
     Point3D* b= new Point3D(0,0,-8);
     model->addFace(f, ul, ur, 0.2,0.2,0.4);
     model->addFace(f, ul, ml, 0,0,0);
     model->addFace(f, bl, ml, 1,0,0);

     model->addFace(f, ur, mr, 0,0,0);
     model->addFace(f, br, mr, 1,0,0);
     model->addFace(f, bl, br, 1,0,0);

     model->addFace(b, ul, ur, 0.2, 0.2, 0.4);
     model->addFace(b, ul, bl, 1, 1, 1);
     model->addFace(b, ur, br, 1, 1, 1);
     model->addFace(b, bl, br, 1, 1, 1);

     Point3D* wingFL1 = new Point3D(-16,0,0);
     Point3D* wingFL2 = new Point3D(-16,0,-8);
     Point3D* wingFR1 = new Point3D(16,0,0);
     Point3D* wingFR2 = new Point3D(16,0,-8);

     model->addFace(wingFL1, wingFL2, ml, 0,0,1);
     model->addFace(wingFR1, wingFR2, mr, 0,0,1);

     Point3D* wingBL = new Point3D(-8, 0, -16);
     Point3D* wingBR = new Point3D(8, 0, -16);

     model->addFace(wingBL, wingBR, b, 0,0,1);
}




#endif

main.cpp

/**************************
 * Includes
 *
 **************************/

#include <windows.h>
#include <gl/gl.h>
#include "defines.h"
#include "gameworld.h"


/**************************
 * Function Declarations
 *
 **************************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);

Camera* camera;
World* world;
Controller* player;


/**************************
 * WinMain
 *
 **************************/

int WINAPI WinMain (HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine,
                    int iCmdShow)
{
    WNDCLASS wc;
    HWND hWnd;
    HDC hDC;
    HGLRC hRC;        
    MSG msg;
    BOOL bQuit = FALSE;
    float theta = 0.0f;

    /* register window class */
    wc.style = CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "GLSample";
    RegisterClass (&wc);

    /* create main window */
    hWnd = CreateWindow (
      "GLSample", "OpenGL Sample", 
      WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
      0, 0, w, h,
      NULL, NULL, hInstance, NULL);

    /* enable OpenGL for the window */
    EnableOpenGL (hWnd, &hDC, &hRC);


    camera = new Camera(new Point3D(0,32,0), 0,0);
    world = new World();

    double s=16;

    Model* speedo = new Model(new Point3D(0,16+8,64), world);
    Controller* controller = new Controller(speedo);
    controller->dx = ANGLE_V*20;
    player = new Controller(camera);
    speedoM(controller, speedo);




    /* program main loop */
    while (!bQuit)
    {
        /* check for messages */
        if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
        {
            /* handle or dispatch messages */
            if (msg.message == WM_QUIT)
            {
                bQuit = TRUE;
            }
            else
            {
                TranslateMessage (&msg);
                DispatchMessage (&msg);
            }
        }
        else
        {
            /* OpenGL animation code goes here */
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable( GL_BLEND );
            glClearColor (1.0f, 1.0f, 1.0f, 0.0f);
            glClear (GL_COLOR_BUFFER_BIT);

            glPushMatrix ();
            glBegin (GL_TRIANGLES);
            controller->update();



            speedo->update();
            player->update();
            world->view(camera);
            glEnd ();
            glPopMatrix ();

            controller->dx = -controller->dx;

            SwapBuffers (hDC);

            theta += 1.0f;
            Sleep (1);
        }
    }

    /* shutdown OpenGL */
    DisableOpenGL (hWnd, hDC, hRC);

    /* destroy the window explicitly */
    DestroyWindow (hWnd);

    return msg.wParam;
}


/********************
 * Window Procedure
 *
 ********************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
                          WPARAM wParam, LPARAM lParam)
{

    switch (message)
    {
    case WM_CREATE:
        return 0;
    case WM_CLOSE:
        PostQuitMessage (0);
    case WM_DESTROY:
        return 0;

    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_ESCAPE:
            PostQuitMessage(0);
            return 0;
        case VK_LEFT:
             player->dx-=ANGLE_V;
             return 0;
        case VK_RIGHT:
             player->dx+=ANGLE_V;
             return 0;
        case VK_UP:
             player->dy-=ANGLE_V;
             return 0;
        case VK_DOWN:
             player->dy+=ANGLE_V;
             return 0;
        case VK_a:

             return 0;
        case VK_d:

             return 0;
        case VK_s:
             player->speed+=MOVE_V;
             return 0;
        case VK_w:
             player->speed-=MOVE_V;
             return 0;


        return 0;
        }

    default:
        return DefWindowProc (hWnd, message, wParam, lParam);
    }
}


/*******************
 * Enable OpenGL
 *
 *******************/

void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;

    /* get the device context (DC) */
    *hDC = GetDC (hWnd);

    /* set the pixel format for the DC */
    ZeroMemory (&pfd, sizeof (pfd));
    pfd.nSize = sizeof (pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | 
      PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    iFormat = ChoosePixelFormat (*hDC, &pfd);
    SetPixelFormat (*hDC, iFormat, &pfd);



    /* create and enable the render context (RC) */
    *hRC = wglCreateContext( *hDC );
    wglMakeCurrent( *hDC, *hRC );

}


/******************
 * Disable OpenGL
 *
 ******************/

void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
    wglMakeCurrent (NULL, NULL);
    wglDeleteContext (hRC);
    ReleaseDC (hWnd, hDC);
}

I am developing this using dev C++ on Windows 7.

I really hope someone could help me. I have checked almost all existing threads on the internet by searching the error message on google but no thread did help me. I would be thankful for answers and I will not know how to thank the person who solves my problem.

I recommend running a debug build of your program from your IDE.
There should be an option somewhere to Debug, or start debugging, or some-such. I haven't used Dev-c++ for at least 8 years, so I really can't remember a lot about it.

Anyway, switch your build profile to a debug build, which will include additional information in your executable that will aid your debugging session. Then build your program in debug mode and start running/debugging your program.
When your program eventually crashes, you should get the option to break out at the line where the program crashes.

If the debugger breaks out at a line of code in your program, then congratulations, you have found where your crash is occurring. Now you need to work out why that line of code is failing. So stick a few breakpoints somewhere near that line of code and run another debug build. Every time a breakpoint is hit, you'll be taken back to your IDE at the appropriate line and you can step through the code and examine the state of any variables that are in scope. And you can check other things like the current call-stack etc. With a bit of time and persistence, you should be able to work out what the problem is.

If the debugger breaks you out to a disassembled version of a system file/library, you need to take a look at your call-stack window and track back through the call-stack to the first line of your code. As soon as you see a line of code in a file that you wrote: Congratulations, that's the point in your program where your crash is occurring.

Basically, in these cases; the chances are it's a call to a function in a library which is failing because of an invalid parameter passed to it by a line of code in your progam. In very rare cases, it could be a bug with a library. But more often than not (99.999% of the time), it will be your own code that is the problem!

From a quick scan-through of your code, nothing jumps out immediately. So without running your code through a debugger myself, I couldn't tell you what the problem is. It could be a stray/uninitialised pointer, a memory leak, an uninitialised variable passed to a function etc. But I don't run Windows on any of my machines at home, so I can't debug your code for you.

The best advice I can give ATM is learn to use your debugger!

EDIT: From re-reading the symptoms you listed in your post; it sounds like it could be a memory leak, or something going into an infinite loop - Again, you'll have to use your debugger and verify this for yourself!

Edited 2 Years Ago by JasonHippy

I would have to disagree with JasonHippy.. the debugger is not gonna help you in this case.

Even before looking at the code, just by the description of the symptoms, it was very obvious to me that this is a memory issue, and most likely a combination of leaks and uninitialized memory. This means that you were not deleting memory that you've allocated, and that you are accessing memory that you have not allocated or not initialized. This is why the debugger won't help you much, because these kinds of errors are not traceable using a debugger, even with a memory profiler it is really hard to trace, and also because the error is not one thing, it's everything.

After looking at your code (not in details, obviously, because this is a lot to look at), it only confirmed my suspicions. You have an enormous amount of leaks in that code. Are you aware that, in C++, you have to delete anything that you've allocated with new? You allocate objects with new everywhere (far more than you should), and there is not a single delete statement anywhere. This is bound to leak memory all over the place. This is why the program runs for a while but then eventually becomes extremely slow and almost at a stand-still. Also, OS or library protections are sometimes in place to prevent your program from consuming so much memory that it overwhelms the entire system, and usually, these protections will "terminate the program in an unusual way", exactly as that error says. This is extremely typical of memory leaks.

Another problem I spotted in your code was this function (around line 100):

         Point3D* Center(){
                  Point3D* p = new Point3D(
                           (point[0]->x+point[1]->x+point[2]->x)/3,
                           (point[0]->y+point[1]->y+point[2]->y)/3,
                           (point[0]->z+point[1]->z+point[2]->z)/3
                  );
         }

This is a function that is supposed to return a pointer to a Point3D, but the function has not return statement, meaning that it will return a pointer that points anywhere. If that pointer is used, it will cause a access violation error (or segmentation fault), or worse, much worse, like causing a memory corruption problem.

By the way, this kind of an error should have been caught by the compiler, as a warning message. You should always compile the code with the highest warning levels and treat those warnings as errors (i.e., fix them all)!

The real core of the issue is that you have a lot to learn about how to program in C++. You use raw pointers far too much, far too much. C++ is a language oriented towards "value-semantics", i.e., the natural way to create and pass objects around is by value, especially for small objects. Even when you want to create or pass around objects by pointer, you put that pointer inside a small object that you create and pass around by value, these are called smart-pointers.

I suspect you come from a reference-semantics language, like Java or C#, and that you are trying to carry over your coding habits into C++. This is not gonna work. You are coding as if you were coding in a garbage-collected, reference-semantics language. In C++, this is about as goofy as sticking a steering wheel on a motorcycle, it's just wrong. If someone told you that this was the correct way to do things in C++, then don't take any advice from that person again.

I good start might be to read my tutorials on resource-management and on ownership design. But I'm not gonna lie, you have a long way to go.

Comments
Ooops, I missed that! Good save!

Just to add to Mike's words on memory leaks, you're running this on a Windows machine, but if you were running on a *nix, you could use valgrind to identify your memory leaks for you; granted, it's pretty easy in this case (a bazillion new, no delete - memory leak city). valgrind runs slow, so it's not appropriate for every situation, but it does a pretty good job; I typically run my programs with it just as a quality control check.

Wow, coming back to it with a fresh set of eyes, I see what you mean Mike.

I'm not sure how I missed seeing all of those new's last night, they actually stick out like a sore thumb don't they?! :/

In my defense, I did write that post at stupid O'clock in the morning after a very long day. It was one of the last posts I made before bed yesterday (or this morning) So I was pretty frazzled!

When I scanned through the code, I'll admit, I didn't read every line. I just very quickly (and lazily) scrolled through, the structure of the code generally looked OK. And I'm guessing I must have scrolled past some of those blocks containing lots of new statements, because ordinarily there's no way I would have missed something like that! :/ Shocking!

Edited 2 Years Ago by JasonHippy

Jason, I know what you mean, though I do some of my best work at stupid o'clock, after a couple of shots of good scotch. My head hits the keyboard, and it finishes the task for me! :-)

hi Again! Thank you for your replies which I learned a lot of. I have learned a lot from your answers.

I did never actually know that I got to delete for each new.

when Mike mention the Center() method in class Triangle I was stunned that I didn't discovered that. the function Center() is infact used very often. in fact it is used each loop when it controlls whether the triangles are sorted or not. before I posted this I didn't know why it didn't work as it should. now when I look at the code and see that I don't return anything from the function, I don't understand why it worked at all. the compiler should give a serious error, or the program should crash imidiately if it doesn't break the laws of C++.

I can tell you all that I haven't learned C++ from any person. in fact I had learned it through the internet and by practice and I am still learning c++ by checking codes on web and forums, like this.

Mike also said that I come from java or C#. that's quite true. I am not coding C#, but I am normally coding java and actually my favourite programming language is Python.

now when I look at the code and see that I don't return anything from the function, I don't understand why it worked at all. the compiler should give a serious error, or the program should crash imidiately if it doesn't break the laws of C++.

Yeah, this is something to get to know about C++. There are a few different levels of "serious error" in C++.

First, there are compilation errors, i.e., when the code just doesn't compile, but that is usually restricted to syntax errors (i.e., code that breaks the syntax rules of C++), not so much logical errors or "bugs" (although, there are advanced techniques in C++ to get the compiler to detect logical errors and bugs, but I won't get into that here).

Then, you have run-time errors, but these are also limited by how much error checking you do in your code, because the C++ language tries to be an "opt-in" language in the sense that most run-time checks are things that the programmer can choose to adopt in his code (or by compiler options), but they are generally not there by default, as they hinder performance. And because C++ is native (does not run in an interpreter or virtual machine) there are very little built-in safety checks, only the most critical ones (like memory overflows or access violations), and generally, these just terminate the application with no further information about the errors.

Then, arguably the most important class of "serious errors" is what we call "undefined behavior" (or UB for short). C++ is a standardized language, and as such, compilers and programmers have to try, as much as possible, to follow the standard as a reference about what should happen when you compile and run a specific piece of code. However, the standard is full of "holes", so to speak, which are mostly intentionnal (to give freedom to compiler developers, so they can optimize and stuff). These holes are things that the standard simply says "if you run this code, anything could happen", i.e., the behavior of the code is "undefined". The catch here is that compilers are generally not required to point out that some piece of code is UB, and often when you run UB code it kind of works or does something not too crazy, or it works sometimes but not other times. In other words, they are a nightmare to find or debug. This is why watching out for UB is very important.

This is exactly where you fall with that Center() function. If a function lacks a return statement (when it has a return type), the behavior is undefined. In most cases, what happens is that the return-value is actually some piece of uninitialized memory, or the old value of one of the local variables of the function. So, the code still runs, but the behavior is undefined or weird, or OK, or sometimes it works in debug mode but not in release mode, and so on..

Really, what you need to do is compile the code with the highest possible warning level and treat them as errors. Most compilers will point out most of the obvious UB cases as warnings. Warnings are almost always important to take care of, there are only some warnings that are less important, but these are always very easy to fix to silence the compiler. To compile will all warnings, you should be able to find the option in your buid-configuration in your IDE, or you can add the compiler option -Wall (for GCC / Clang / ICC) or /Wall (for the Microsoft compiler).

in fact I had learned it through the internet and by practice and I am still learning c++ by checking codes on web and forums, like this.

You might want to consider following more authoritative works on C++. It's just that the signal-to-noise ratio on the web for good teachings about C++ is not that great (except here, of course!). You might want to check our thread on book recommendations here. I would recommend C++ Primer.

This question has already been answered. Start a new discussion instead.