Advertisement

GLUT window close and dynamic memory allocation.

Started by September 13, 2002 01:48 AM
1 comment, last by camcbri 22 years, 4 months ago
Hello! I'm having a problem with a little GLUT program I wrote... I think that I'm either A) deallocating memory and then trying to access it or B) not deallocating the memory at all. I get an "error report" when I close my application. Could any of you kind souls check out this source, maybe compile and tell me what I'm doing that is stupid? The glut main functions...
    
//*****************************************************************************

//* File:   main.cpp

//* Author: Chris McBride

//* Date:   13 September 02

//* Desc:   This is a main GLUT driver

//* 

//* Revision List & Date:

//*   none.

//*

//*  HEY YOU!  Use a command line argument to set the number of vertices.

//* 

//*****************************************************************************

#include <iostream>
#include <gl/glut.h>
#include "callbacks.h"
#include "point.h"

int g_width  = 1024;
int g_height = 768;

int main(int argc, char* argv[])
{
   if(argc > 1)
	   numVertices = atoi(argv[1]);
   else
      numVertices = 23;

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);

	//* Specify to GLUT what full screen resolution to use.

	glutGameModeString("1024x768:32@60");

	//* Check if requested mode is supported.

	if(glutGameModeGet(GLUT_GAME_MODE_WIDTH != 1))
	{
		//* Mode IS supported, register callbacks, etc.

		glutEnterGameMode();
		glutKeyboardFunc(myKeyboard);
		glutDisplayFunc(myDisplay);
		glutReshapeFunc(myReshape);
		glutIdleFunc(myIdle);
  	}
	else
	{
		//* Mode is NOT supported.  Tell user and exit.

		std::cout << "The requested video mode is not supported."
			      << std::endl;

		return -1;
	}

	//* Perform program initializations then start main loop.

	myInit();
	glutMainLoop();
	
	return 0;
}
  
Code to draw Rosette's...
  
//*****************************************************************************
//* File:   rosette.h
//* Author: Chris McBride
//* Date:   13 September 02
//* Desc:   This contains two functions for drawing Rosettes, and could be 
//*         mathematically described as "complete Hamiltonian circuits."
//*
//* Revision List & Date:
//*   none.
//*****************************************************************************
#ifndef ROSETTE_H
#define ROSETTE_H

#include "point.h"
#include <gl/gl.h>

//* ---------------------------------------------------------------------------
//* Rosette_odd
//*
//* This function will draw a Rosette from any arbitray number of odd vertices.
//* ---------------------------------------------------------------------------
void Rosette_odd(const int someOdd, const point2 vertices[])
{
   return;
}

//* ---------------------------------------------------------------------------
//* Rosette_prime
//*
//* This function is special to draw a Rosette with a prime number of vertices.
//* ---------------------------------------------------------------------------
//* For the special case of prime numbers, we can start at the "start vertex" 
//* and complete all the moves necessary without ever starting a "loop" at 
//* another vertex.
//*
//* We know that "loops" will NEVER be greater than (n-1)/2 and all vertex 
//* skipping below that number must also be completed. (this means that you 
//* must skip every fourth, every third, every second, and finally, you must 
//* do every vertex that is right next to the current one.
//* ---------------------------------------------------------------------------
void Rosette_prime(const int primeNumber, const point2 vertices[])
{
   static int loops = (primeNumber - 1) / 2;
   int startVert	 = 0;	/* The first vertex of the iteration */
   int currVert	 = 0;   /* Holds the current vertex we're drawing */
   int workingVert  = 0;   /* To do calculation only once */

   //* Skip "loops" number of vertices, then loops-1, loops-2, ...

   //* until loops = 1.  At loops = 1, we are essentially just

   //* drawing a line from a vertex to the vertex next to it.

   for(int i=loops; i>0; i--)
   {
      do
      {
         glVertex2f(vertices[currVert].x, vertices[currVert].y);

         //* Since we are working with vertices 0 - primeNumber, we

         //* have to convert the skip values.

         //* For example, a 3 vertices skip on a 13 vertices graph

         //* starting at vertex 11 would say to skip to vertex 14...

         //* vertex 14 doesn't exist, so turn that 14 into 0 with this.

         workingVert = currVert + i;
         if(workingVert >= primeNumber)
         {
            currVert = workingVert - primeNumber;
         }
         else
         {
            currVert = workingVert;
         }

      } while(currVert != startVert);

      glVertex2f(vertices[0].x, vertices[0].y);
   }

   return;
}

#endif
  

  
A simple point class to play around with.
      
//*****************************************************************************

//* File:   point.h

//* Author: Chris McBride

//* Date:   13 September 02

//* Desc:   This contains the definition for two simple point classes for 

//*         representing a point in 2 dimensions or 3 dimensions.

//*

//* Revision List & Date:

//*   none.

//*****************************************************************************

#ifndef POINT_H
#define POINT_H

class point2
{
	public:
      point2();
      ~point2();
      point2(const point2& p);
      point2& operator= (const point2& rhs);
      bool operator!= (const point2& rhs);
      bool operator== (const point2& rhs);

		float x;
		float y;
};

point2::point2()
: x(0.0f),
  y(0.0f)
{
   return;
}

point2::~point2()
{
   return;
}

point2::point2(const point2& p)
{
   x = p.x;
   y = p.y;
   return;
}

point2& point2::operator= (const point2& rhs)
{
   if(*this != rhs)
   {
      x = rhs.x;
      y = rhs.y;
   }

   return *this;
}

bool point2::operator== (const point2& rhs)
{
   bool retVal = false;

   if(x == rhs.x && y == rhs.y)
      retVal = true;

   return retVal;
}

bool point2::operator!= (const point2& rhs)
{
   bool retVal = false;

   if(x != rhs.x || y != rhs.y)
      retVal = true;

   return retVal;
}

class point3
{
	public:
      point3();
      ~point3();
      point3(const point3& p);
      point3& operator= (const point3& rhs);
      bool operator != (const point3& rhs);
      bool operator == (const point3& rhs);

		float x;
		float y;
		float z;
};

point3::point3()
: x(0.0f),
  y(0.0f),
  z(0.0f)
{
   return;
}

point3::~point3()
{
   return;
}

point3::point3(const point3& p)
{
   x = p.x;
   y = p.y;
   z = p.z;
   return;
}

point3& point3::operator= (const point3& rhs)
{
   if(*this != rhs)
   {
      x = rhs.x;
      y = rhs.y;
      z = rhs.z;
   }

   return *this;
}

bool point3::operator== (const point3& rhs)
{
   bool retVal = false;

   if(x == rhs.x && y == rhs.y && z == rhs.z)
      retVal = true;

   return retVal;
}

bool point3::operator!= (const point3& rhs)
{
   bool retVal = false;

   if(x != rhs.x || y != rhs.y || z != rhs.z)
      retVal = true;

   return retVal;
}

#endif
    
Here are the callbacks and my init. NOTICE that the memory is allocated into the global variable in init and then deallocated in the keyboard handler...
        
//*****************************************************************************

//* File:   callbacks.h

//* Author: Chris McBride

//* Date:   13 September 02

//* Desc:   This is a bunch of GLUT callback function definitions, as well as

//*         my initialization functions.

//*

//* Revision List & Date:

//*   none.

//*****************************************************************************

#include <iostream>
#include <cmath>
#include <gl/glut.h>
#include "rosette.h"
#include "point.h"

int numVertices  = 0;
point2* vertices = 0;
bool done = false;

const double PIOVER180 = (3.14159265359 / 180);

//* ---------------------------------------------------------------------------

//* BuildVertices

//*

//* This function takes in the number of vertices you want to divide a circle

//* into (evenly) and returns a pointer to a structure of points that tell 

//* you where those vertices should be.

//* ---------------------------------------------------------------------------

//point2* BuildVertices(const int numVertices)

void BuildVertices(const int numVertices, point2 verts[])
{
   //point2* verts = new point2[numVertices];

   float theta = 360.0f / numVertices;
   int j = 0;

   for(float i=0; i<360; i+=theta)
   {
      verts[j].x = sin(i * PIOVER180);
      verts[j].y = cos(i * PIOVER180);

      std::cout << "vertex " << j << " x: " << verts[j].x;
      std::cout << std::endl;
      std::cout << "vertex " << j << " y: " << verts[j].y;
      std::cout << std::endl;
      std::cout << "angle: " << i << std::endl;
      std::cout << std::endl;

      ++j;
   }

   //return verts;

   return;
}

//* ---------------------------------------------------------------------------

//* myKeyboard

//*

//* If you don't know...

//* ---------------------------------------------------------------------------

void myKeyboard(unsigned char key, int mouseX, int mouseY)
{
   switch(key) {
   case 27:    // 27 is ASCII for Escape key

      done = true;
      delete [] vertices;
      exit(1);
      break;
   case 'q':
      break;
   default:
      break;
   }
   return;
}

//* ---------------------------------------------------------------------------

//* myDisplay

//*

//* If you don't know...

//* ---------------------------------------------------------------------------

void myDisplay()
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glLoadIdentity();

   if(!done)
   {
      glBegin(GL_LINE_STRIP);
         //Rosette_odd(numVertices, vertices);

         Rosette_prime(numVertices, vertices);
      glEnd();
   }

   glutSwapBuffers();
   return;
}

//* ---------------------------------------------------------------------------

//* myReshape

//*

//* If you don't know...

//* ---------------------------------------------------------------------------

void myReshape(int width, int height)
{
   glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

   glViewport(0, 0, width, height);

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(-1.165f, 1.165f, -1.0f, 1.0f, 1.0f, -1.0f);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   return;
}

//* ---------------------------------------------------------------------------

//* myIdle

//*

//* If you don't know...

//* ---------------------------------------------------------------------------

void myIdle()
{
   glutPostRedisplay();
   return;
}

//* ---------------------------------------------------------------------------

//* myInit

//*

//* If you don't know...

//* ---------------------------------------------------------------------------

void myInit()
{
   //vertices = BuildVertices(numVertices);

   vertices = new point2[numVertices];
   BuildVertices(numVertices, vertices);

   glPointSize(3.0f);
   glLineWidth(1.0f);
   return;
}
    
Thanks a ton! [edited by - camcbri on September 13, 2002 2:52:31 AM]
just in case anyone is searching...

I found the source of the error... Not GLUT at all. Must remember the first rule of programming (blame your own code first).

The problem was round off error in BuildVertices

  void BuildVertices(const int numVertices, point2 verts[]){   float theta = 360.0f / numVertices;   //int j = 0;   //* THIS LOOP ALLOWS ROUND OFF ERROR... THEREFORE, THE LOOP   //* MAY RUN ONE EXTRA TIME (ie if i=359.876543) THUS OVER-   //* WRITING MEMORY!   //for(float i=0; i<360; i+=theta)   //* change to:   float i = 0.0f;   for(int j=0; j< numVertices; j++)   {      verts[j].x = sin(i * PIOVER180);      verts[j].y = cos(i * PIOVER180);      std::cout << "vertex " << j << " x: " << verts[j].x;      std::cout << std::endl;      std::cout << "vertex " << j << " y: " << verts[j].y;      std::cout << std::endl;      std::cout << "angle: " << i << std::endl;      std::cout << std::endl;      //++j;      i += theta;   }   return;}  
Advertisement
Well, I''m glad you found your error.

I just wanted to say that you have VERY well commented code. It''s very unusual to see that. I don''t know what GLUT is, and I''m still pretty new to programming, but all your comments allowed me to follow your code fairly easily.

I still wouldn''t of been able to find the error, but oh well. Have fun programming!

~~~~~~~~~~~
Chris Vogel
~~~~~~~~~~~
WyrmSlayer RPG - In Early Development

This topic is closed to new replies.

Advertisement