-
Vector, class, and iterator issues
Hello, I'm new to this forum.
I'm making a Combat addon fro the space flight simulator, orbiter (www.orbitersim.com). You include compiled libraries to make the addons. I'm pretty sure my problem is not orbiter specific, though. Here is the code that is causing my error:
Code:
DLLCLBK void opcPreStep(double simt, double simdt, double mjd)
{
//loop through all weapons, and destroy them.
for (vector<Weapon>::iterator it = WeaponList.begin(); it != WeaponList.end();++it)
{
it->explode();
}
};
opcPreStep is called by the core every timestep. WeaponList is a vector of the Weapon class.
I compile my addon, and I get a crash to desktop. If I change it to *it, I get an illegal indirection error. can anyone help? thanks.
-
Re: Vector, class, and iterator issues
- Thanks for using code tags.
- The problem isn't in the snippet that you've posted.
- Lose the last semicolon.
- After you've fixed the underlying issue, if all you're doing is calling destroy in opcPreStep, then you can replace your for-loop with the cleaner std::for_each variant:
Code:
std::for_each(WeaponList.begin(), WeaponList.end(), std::mem_fun_ref(&Weapon::explode));
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Plasmator
- Thanks for using code tags.
- The problem isn't in the snippet that you've posted.
- Lose the last semicolon.
- After you've fixed the underlying issue, if all you're doing is calling destroy in opcPreStep, then you can replace your for-loop with the cleaner std::for_each variant:
Code:
std::for_each(WeaponList.begin(), WeaponList.end(), std::mem_fun_ref(&Weapon::explode));
Thank you for the quick reply.
Where do you think the problem lies, then? Persumably the WeaponList vector? Or perhaps the Weapon class?
Here is the declaration of the weapon class;
Code:
//The Weapon class.
class Weapon {
//for safety, all variables are accessed privately.
private:
int FireVesselIndex;
const char *explodemesh; //A mesh to be spawned on explosion.
const char *name; //The name of the weapon.
const char *classname; //Classname (CFG File) of the vessel to be 'fired'
bool missile; //Whether it's a missile (full throttle on fire) or not.
bool exploded; //Whether the vessel has exploded or not.
bool fired; //Whether the vessel has been fired or not.
public:
Weapon(const char *newname,const char *newclassname, bool newmissile); //Constructor.
~Weapon() {} //Destructor.
bool fire(); //The fire function.
bool explode(); //The explode function - replaces the current mesh with the explosion mesh.
//Update status function.
void UpdateStatus() {
this->vessel->GetStatusEx(&stat);
}
OBJHANDLE objvessel; //The OBJHANDLE for the weapon.
VESSEL *vessel; //The VESSEL handle for the weapon.
VESSELSTATUS2 stat; //The current status of the weapon. Given properties on fire.
//Set functions- for changing private data.
void SetExplodeMesh(const char*newexplodemesh){
explodemesh=newexplodemesh;
}
};
You may not recognise some data types, such as OBJHANDLE etc - they are ORbiter specific.
Thanks for helping.
-
Re: Vector, class, and iterator issues
The Weapon class with all that pointer members should propably have a copy constructor and an assignement operator.
But then it seems to be incomplete and I can't tell for shure.
Kurt
-
Re: Vector, class, and iterator issues
As ZuK pointed out, there's not enough information to determine the root cause of your problem(s).
Having said that, start taking advantage of standard facilities such as std::string -- they'll make your life a lot easier.
P.S.: Debuggers are very useful tools. ;)
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Plasmator
As ZuK pointed out, there's not enough information to determine the root cause of your problem(s).
Having said that, start taking advantage of standard facilities such as std::string -- they'll make your life a lot easier.
P.S.: Debuggers are very useful tools. ;)
I have to use const char, because that's what the APIs require. I can't use a debugger either, because Orbiter has no built in debugging information.
EDIT: more info on my problem;
I can run an empty iterating loop through the vector fine, I only get a CTD after using a member function of the iterator's class (Weapon). I've checked that there is nothig wrong with explode().
The initialisation of the vector:
Code:
//This vector contains all Weapons in the scenario. Weapons are added on construction.
vector <Weapon> WeaponList;
ANOTHER EDIT:
Ok, I've managed to get vc's debugger working with orbiter - got this -
First-chance exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
Unhandled exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
First-chance exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
Unhandled exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
First-chance exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
Unhandled exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
First-chance exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
Unhandled exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
First-chance exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
Unhandled exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
First-chance exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
Unhandled exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
First-chance exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
Unhandled exception at 0x00414d6c in orbiter.exe: 0xC0000005: Access violation reading location 0xc304d107.
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by Escapetomsfate
I have to use const char, because that's what the APIs require.
You can get a const char* from a std::string by way of the c_str() member function.
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Escapetomsfate
I have to use const char, because that's what the APIs require. I can't use a debugger either, because Orbiter has no built in debugging information.
EDIT: more info on my problem;
I can run an empty iterating loop through the vector fine, I only get a CTD after using a member function of the iterator's class (Weapon). I've checked that there is nothig wrong with explode().
The initialisation of the vector:
Code:
//This vector contains all Weapons in the scenario. Weapons are added on construction.
vector <Weapon> WeaponList;
Then use this:
Code:
std::string someString = "My foo is great";
// some API function which takes const char * as a argument
void somAPIFoo(const char *text);
// and you call this like this:
somAPIFoo(someString .c_str());
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Escapetomsfate
I have to use const char, because that's what the APIs require. I can't use a debugger either, because Orbiter has no built in debugging information.
EDIT: more info on my problem;
I can run an empty iterating loop through the vector fine, I only get a CTD after using a member function of the iterator's class (Weapon). I've checked that there is nothig wrong with explode().
The initialisation of the vector:
Code:
//This vector contains all Weapons in the scenario. Weapons are added on construction.
vector <Weapon> WeaponList;
Then use this:
Code:
std::string someString = "My foo is great";
// some API function which takes const char * as a argument
void somAPIFoo(const char *text);
// and you call this like this:
somAPIFoo(someString.c_str());
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
STLDude
Then use this:
Code:
std::string someString = "My foo is great";
// some API function which takes const char * as a argument
void somAPIFoo(const char *text);
// and you call this like this:
somAPIFoo(someString.c_str());
Can I ask why it is necessary to use std::string and then convert, when you can just pass a const char?
I've been learning c++ for a month or so, and I don't really understand why some functions are 'safer' than others- can someone please explain?
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by Escapetomsfate
Can I ask why it is necessary to use std::string and then convert, when you can just pass a const char?
So you are relieved of the burden of memory management. Also, when you do need to manipulate strings other than with the API that you are using, it tends to be safer and easier due to the functions provided.
-
Re: Vector, class, and iterator issues
When dealing with char arrays, you either have to settle for fixed-size arrays (limiting your string length), or else you need to use dynamic allocation (new/delete or malloc/free) to make sure you always have a big enough array.
For numerous reasons, getting dynamic allocation "right" in complex cases is nontrivial. Even experts can screw it up---don't allocate enough space and have a buffer overrun, forget to allocate a new array in a class's copy constructor, or simply fail to delete an array and end up with a memory leak. It's a pain.
std::string wraps all that difficult logic up in a clean, easy-to-use container that it's hard to screw up with.
-
Re: Vector, class, and iterator issues
OP: you should be able to step through your code with the help of VS's debugger as long as your binary exposes debug symbols.
You can either use a hard breakpoint (i.e., the VS JIT-Debugger dialog will be spawned), or attach to your target process (see the "Attach to Process" under Tools) and wait for an IDE breakpoint to be hit.
As I said earlier, debuggers are useful tools...
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Plasmator
OP: you should be able to step through your code with the help of VS's debugger as long as your binary exposes debug symbols.
You can either use a hard breakpoint (i.e., the VS JIT-Debugger dialog will be spawned), or attach to your target process (see the "Attach to Process" under Tools) and wait for an IDE breakpoint to be hit.
As I said earlier, debuggers are useful tools...
Can you do this with DLLs? that's what I'm making.
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Escapetomsfate
Can you do this with DLLs?
Aye.
Quote:
Originally Posted by
Escapetomsfate
that's what I'm making.
Yes, this was evident from your first post.
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Plasmator
Aye.
Yes, this was evident from your first post.
Oh Yeah.....
So how do I set it up?
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Escapetomsfate
Oh Yeah.....
So how do I set it up?
Below are links to a short movie (recorded on a test VM; quality should be acceptable) that illustrates one of the methods that I was talking about.
You may also need VMware's Movie Decoder if you don't have one of their products installed.
Hopefully you'll be able to do this on your own from now on...
Debugger.7z (~700 kB)
http://plasmator.t35.com/DebuggerSFX.zip (Can't link this one, retarded host) [7-zip Self-Extracting Archive] (~800 kB)
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Plasmator
Below are links to a short movie (recorded on a test VM; quality should be acceptable) that illustrates one of the methods that I was talking about.
You may also need
VMware's Movie Decoder if you don't have one of their products installed.
Hopefully you'll be able to do this on your own from now on...
Debugger.7z (~700 kB)
http://plasmator.t35.com/DebuggerSFX.zip (Can't link this one, retarded host) [7-zip Self-Extracting Archive] (~800 kB)
Thanks plasmator, really helpful :)
I really don't know which window shows what the problem is. This is the registers window;
Code:
EAX = 00079D40 EBX = 00079B30 ECX = 00079D18 EDX = 00000000 ESI = 0178743C EDI = 0007A7BB EIP = 00000000
ESP = 00A9FE40 EBP = 00000000 EFL = 00200202
and this is from output:
Code:
First-chance exception at 0x00000000 in orbiter.exe: 0xC0000005: Access violation reading location 0x00000000.
Unhandled exception at 0x00000000 in orbiter.exe: 0xC0000005: Access violation reading location 0x00000000.
Does anyone know wha that could mean, in relation to the code at the start?
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Escapetomsfate
Code:
First-chance exception at 0x00000000 in orbiter.exe: 0xC0000005: Access violation reading location 0x00000000.
Unhandled exception at 0x00000000 in orbiter.exe: 0xC0000005: Access violation reading location 0x00000000.
Does anyone know wha that could mean, in relation to the code at the start?
You are accessing an address via pointer for reading, and that address you're attempting to access is NULL (0x00000000).
Set a breakpoint on the very first line of your application, and keep your eye on the Output Window. If that message hasn't appeared when the first line is about to execute, single step through the program until that message appears. When that message appears, then that area of code is where it's triggering that message.
Usually reading from a NULL address isn't fatal, but irritating seeing that message. The fatal one is when you attempt to write to a NULL address.
If that message appears before the first line in your main() program, then either you have global classes, objects, that were instantiated, and that is the cause of the problem, or if you're using other DLL's that get loaded at app startup, then they could be the ones causing the problem. You need to just debug slowly to pinpoint where that message is being generated from.
BTW, since you are using Visual C++, you should have posted this in either the Visual C++ forum (if using MFC) or the Windows API forum (if you're using straight Windows API calls).
Regards,
Paul McKenzie
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Paul McKenzie
You are accessing an address via pointer for reading, and that address you're attempting to access is NULL (0x00000000).
Set a breakpoint on the very first line of your application, and keep your eye on the Output Window. If that message hasn't appeared when the first line is about to execute, single step through the program until that message appears. When that message appears, then that area of code is where it's triggering that message.
Usually reading from a NULL address isn't fatal, but irritating seeing that message. The fatal one is when you attempt to write to a NULL address.
If that message appears before the first line in your main() program, then either you have global classes, objects, that were instantiated, and that is the cause of the problem, or if you're using other DLL's that get loaded at app startup, then they could be the ones causing the problem. You need to just debug slowly to pinpoint where that message is being generated from.
BTW, since you are using Visual C++, you should have posted this in either the Visual C++ forum (if using MFC) or the Windows API forum (if you're using straight Windows API calls).
Regards,
Paul McKenzie
Thanks for the help. I already know that this is the code causing the CTD:
Code:
DLLCLBK void opcPreStep(double simt, double simdt, double mjd)
{
//loop through all weapons, and destroy them.
for (vector<Weapon>::iterator it = WeaponList.begin(); it != WeaponList.end();++it)
{
it->explode();
}
}
So, I suppose I have to assign it to something. Any suggestions? :)
EDIT: Could this be it? it is in the Weapon class constructor.
Code:
//add self to WeaponList vector.
WeaponList.push_back(*this);
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Escapetomsfate
Thanks for the help. I already know that this is the code causing the CTD:
There are several lines posted there. Which one is it that is causing the problem?
As others pointed out, we need to see the full context of when, where, and how that code is called, we do not know what the values of any of those variables are when that code is called, etc.
Since this is a runtime issue, we can't do static analysis of source code to show you what you're doing wrong. All we can say is that the loop syntactically is correct. If WeaponList is valid, and if explode() has no issues, then that code is correct (Note the if -- only you know whether any of those things are valid or not).
Regards,
Paul McKenzie
-
Re: Vector, class, and iterator issues
I only get an error when I use a function of the iterator (it, using Weapon class functions).
How do I make a class push back itself on construction? I'm sure that's the problem.
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Escapetomsfate
EDIT: Could this be it? it is in the Weapon class constructor.
Code:
//add self to WeaponList vector.
WeaponList.push_back(*this);
You're adding a copy of a not yet constructed object to a vector. Could very well be a problem especially since you seem to have no copy constructor defined for the Weapon class that has some pointer members.
Kurt
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
Escapetomsfate
I only get an error when I use a function of the iterator (it, using Weapon class functions).
Then that loop would never execute if the WeaponList is empty. Look at the for loop constraints. Second, if that loop did execute, that means that the WeaponList is not empty, and one of the item's in that list has an explode() function that is buggy, or the item itself is buggy.
Quote:
How do I make a class push back itself on construction?
I don't understand your question. How would that fix the issue I stated above?
Quote:
I'm sure that's the problem.
Hopefully you are not guessing at what the problem is. You never should guess, you have to actually debug, find the cause of the problem, and then offer a diagnosis to fix the problem.
Regards,
Paul McKenzie
-
Re: Vector, class, and iterator issues
Quote:
Originally Posted by
ZuK
You're adding a copy of a not yet constructed object to a vector. Could very well be a problem especially since you seem to have no copy constructor defined for the Weapon class that has some pointer members.
Kurt
Of course! duh! Thanks a lot.