By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,557 Members | 1,406 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,557 IT Pros & Developers. It's quick & easy.

Custom C++ Vector Access Control Issues

P: 4
Hi all,
I've had a bit of frustration with making a class and accessing the private variables from the functions. So here's the whole scoop (code snips are located below). I've created my own custom Physics class to emulate physics, and in it I am using a vector to keep track of my ball objects I will create. The problem is that even if I completely initialize 4 balls in the constructor (which works fine by the way) as soon as I try to change their properties or call push_back to make a new object, during run it gives me Access Violations. I know this is due to a bad pointer, but that is why I switched to a vector, because it was supposed to do all the dirty work for me. My code is below, please help!

The things to notice are how a call to the private variable in the "updateBalls()" method seems to work fine. But no matter what I do I can't even make the same call from "createBall()" This is completely baffling me.

Thanks ahead of time!


Physics.h File:
Expand|Select|Wrap|Line Numbers
  1. #include <vector>
  2. #include "3DBalls.h"
  3. #include "Ball.h"
  4.  
  5.  
  6. class Physics
  7. {
  8. private:
  9.     //Ball myBalls[MAXNUMOFBALLS];
  10.     //int numberOfBalls;
  11.     std::vector<Ball> myBalls;
  12.  
  13. public:
  14.     Physics();
  15.     void createBall(D3DVECTOR position, float mass, float radius);
  16.     int getNumOfBalls();
  17.     void collisionDetection();
  18.     void collisionPrediction();
  19.     void addGravity();
  20.     void updateBalls(float timeDelta);
  21.     bool insideBall(float posX, float posY, float posZ, float radius);
  22.     void physicsLoop(float timeDelta);
  23.     D3DVECTOR getBallPosition(int ballNum);
  24.     void release();
  25. };
  26.  

Physics.cpp File
Expand|Select|Wrap|Line Numbers
  1. #include "Physics.h"
  2.  
  3.  
  4. Physics::Physics()
  5. {
  6.     //Need to create struct to handle list of objects
  7.     int i;
  8.     D3DVECTOR temp = {0.0f, 100.0f, 0.0f};
  9.     for(i=0; i<MAXNUMOFBALLS; i++) 
  10.     {
  11.         // Fully initialized Balls from constructor
  12.                                 myBalls.push_back(*(new Ball(temp, 100.0f, 5.0f)));
  13.         temp.z +=30;        
  14.     }    
  15. }
  16.  
  17. void Physics::createBall(D3DVECTOR position, float mass, float radius)
  18. {
  19.                 // If this is commented the program runs fine
  20.                 myBalls.push_back(*(new Ball(position, mass, radius)));
  21.                 // Can't even do this!!!
  22.                 myBalls.at(0).getRadius();
  23. }
  24.  
  25.  
  26. void Physics::updateBalls(float timeDelta)
  27. {
  28.     int i;
  29.     for(i=0; i<myBalls.size(); i++)
  30.     {
  31.         // For some reason this works fine!  It doesn't make sense
  32.                                 myBalls.at(i).calculateNewPosition(timeDelta);
  33.     }
  34. }
Aug 15 '07 #1
Share this Question
Share on Google+
7 Replies


RedSon
Expert 5K+
P: 5,000
Instead of doing two or three operations on a Ball object in one line of code why dont you try breaking it down even more. Then you can see what calls are causing problems. For example

Expand|Select|Wrap|Line Numbers
  1. Ball tempBall = myBall.at(i);
  2. tempBall.calculateNewPosition(timeDelta);
  3. //use debug to verify that the new position was calculated properly
  4. myBall.at(i) = tempBall;
Now you can watch every line of code as it executes and see what the result was.
Aug 15 '07 #2

P: 4
Instead of doing two or three operations on a Ball object in one line of code why dont you try breaking it down even more. Then you can see what calls are causing problems. For example

Expand|Select|Wrap|Line Numbers
  1. Ball tempBall = myBall.at(i);
  2. tempBall.calculateNewPosition(timeDelta);
  3. //use debug to verify that the new position was calculated properly
  4. myBall.at(i) = tempBall;
Now you can watch every line of code as it executes and see what the result was.


Thanks for a quick reply. I guess I should have specified a bit further. I've actually debugged this code line by line and the Access Violation actually occurs inside of the vector class. So somehow the vector pointer is getting corrupt. (possibly a compiler bug?) I'm just looking for some sort of confirmation that I'm not doing something entirely stupid.

The same thing happened when I used my own array of Balls. For some reason when I call createBall() I get access violations no matter which variable I am trying to access. I can created an Int in the class, and for some reason I get Access violations from the createBall(); class, even if I am only trying to read it in memory.

And actually, as long as the Balls are created in the constructor (ie I use a loop to make 5 Balls), all the other code runs fine EXCEPT createBall(). The problem is I would like to make new balls on command.
Aug 15 '07 #3

ilikepython
Expert 100+
P: 844
Thanks for a quick reply. I guess I should have specified a bit further. I've actually debugged this code line by line and the Access Violation actually occurs inside of the vector class. So somehow the vector pointer is getting corrupt. (possibly a compiler bug?) I'm just looking for some sort of confirmation that I'm not doing something entirely stupid.

The same thing happened when I used my own array of Balls. For some reason when I call createBall() I get access violations no matter which variable I am trying to access. I can created an Int in the class, and for some reason I get Access violations from the createBall(); class, even if I am only trying to read it in memory.

And actually, as long as the Balls are created in the constructor (ie I use a loop to make 5 Balls), all the other code runs fine EXCEPT createBall(). The problem is I would like to make new balls on command.
Try storing pointers in the vector:
Expand|Select|Wrap|Line Numbers
  1. Ball *pball = new Ball(position, mass, radius);
  2. myBalls.push_back(pball);
  3.  
That might be difficult if your design depends on objects.
Declare the vector like this:
Expand|Select|Wrap|Line Numbers
  1.     std::vector<Ball *> myBalls;
  2.  
Also, don't forget to free your memory. If you use objects you have to do this:
Expand|Select|Wrap|Line Numbers
  1. Ball *pBall = &myBalls[i]
  2. delete pBall;
  3.  
EDIT: Reading over your post, maybe it's not a good idea because it works fine in the constructor.
Aug 15 '07 #4

Expert 10K+
P: 11,448
Can you show us the copy constructor for the Ball class?

kind regards,

Jos
Aug 15 '07 #5

weaknessforcats
Expert Mod 5K+
P: 9,197
Try storing pointers in the vector:

Code: ( cpp )
Ball *pball = new Ball(position, mass, radius);
myBalls.push_back(pball);
This just ducks the real issue: The Ball class has no proper copy constructor.

It has to be this since vector does move things around when some methods execute.

By having a class of pointers, at least the pointers will copy and the error should go away only to resurface elsewhere when a copy constructor is needed.

Lastly, a vector of pointer is is not a good idea since you can't tell when it's safe to delete the pointer. Certainly, the object can't be deleted if there are other pointers to it in the program. You uses handles in a case like this. That is, you need a vector of handles to Ball. There is an article in the C/C++ Articles forum that shows you how to do this.
Aug 15 '07 #6

P: 4
Can you show us the copy constructor for the Ball class?

kind regards,

Jos


This could be my problem. Being natively used to java, this is my first real C++ program. I've never even heard of a copy constructor requirement. What exactly needs to be in a copy constructor? Is this simply to create a pointer to a new object create with the same attributes? If this is the problem that would be great!
Aug 15 '07 #7

P: 4
Yeah, so I feel like a complete idiot. Horrah for being a noob! Consider this thread closed.

Like the idiot I am I ran a call to "createBall" before I made an instance to the class. I found this out by putting a break point in the constructor and the createBall function. And I was confused when it didn't stop at the break point in the constructor, and when it finally clicked I felt like crawling into a hole.

I thank everyone for their help and I found out I didn't need a copy cconstructor since I don't have pointers inside the ball class, it would simply create its own satisfactory copy constructor.

Thanks Again!
Aug 15 '07 #8

Post your reply

Sign in to post your reply or Sign up for a free account.