|
Unhandled Exception etc...: Access Violation Reading Location 0x00000000 |
bamccaig
Member #7,536
July 2006
|
hey guys! I've been trying to learn Allegro and finally found a tutorial so I started doing it. It is a LoomSoft's tutorials for "Newbies". So far it's going great. It's got me really excited about Allegro! Anyway, while doing the 8th lesson in the series <http://www.loomsoft.net/resources/alltut/alltut_index.htm> I have come across a little snag. My problem is not related to the code in the tutorial. The tutorial is going fine. The problem appears to be with my OO approach to the tutorial. In other words, I've been trying to encapsulate the functionality in classes to simplify the code and clean it up a little. I've attached a copy of the 'project' code so you can compile it yourself and see what's happening <*EDIT* Added link to attachment for convenience: http://www.allegro.cc/files/attachment/591278>. I would give you more for output, but I can't figure out how to get a call stack at the moment and I gotta leave for work in a minute (to work on JavaScript ). Sorry there is no makefile, etc., but I haven't yet learned to write a makefile and I was doing lessons 7 and 8 in Windows with VS .NET 2003 anyway (I did the first 6 in Linux and wanted to see if I could get them working in Windows too). I was going to leave the project files in the loomsoft-tutorial/src/win/ directory, but I wasn't sure if it was legal to distribute them from an educational version of the IDE, etc. Anyway, the project compiles okay, I think, but when I execute the resulting program I get the following: Unhandled exception at 0x004013c0 in lesson8.exe: 0xC0000005: Access violation reading location 0x00000000. I haven't had much time to look into the cause of the problem, but my Google searches didn't return anything related. (The few forums that looked to have the same problem were guided in a different direction and never concluded the exception). I would throw in exception handling to prevent a fatal crash, but the code VS .NET 2003 is pointing to as the cause is not doing anything but setting a member in an accessor method. Granted, the member is also an object, but I thought it was still straight-forward... I honestly haven't had a chance to use C/C++ before now in months. Anyway, I found that my Debug and Release projects appear to throw the same type of exceptions at different points in the code too. Hmmm. If you have a chance please look at, compile, and execute the project and tell me what's wrong; or just tell me what could cause an "access violations" exception. I thought maybe it was related to the public, private, and protected keywords so to rule that out I put everything public temporarily... So don't worry about that, the members were all private/protected. But it's still throwing the same exception. I'd also like feedback on the directory structure of my project since I'm trying to do it the right way. I really prefer the *nix directory structure to Windows'. / - This is the project root, for example, loomsoft-tutorial. Please note the duplicate data directory (/src/data/) is only there so I could get VS .NET 2003 to see them for debugging... I'm not sure of the right way to do it, nor the right place to have the project files vs. the data files. I'd like feedback. Thanks a lot! -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Tobias Dammers
Member #2,604
August 2002
|
Without looking at your project, I'd say you're dereferencing NULL. int* someptr = 0; *someptr = something; // this crashes ...or, more likely, you call a member function of a NULL object. Technically, that in itself isn't a problem (unless the function is virtual), but a member function will typically access member variables, and if you call a member function on a NULL object, this means dereferencing NULL. Example: class foo { protected: int bar; public: void set_bar(int newbar) { bar = newbar; } }; int main() { foo* my_foo = 0; my_foo->set_bar(23); // this will crash return 0; }
--- |
bamccaig
Member #7,536
July 2006
|
Yeah, that sounds like it could be related... I think the objects themselves are instanciated, however, there might be references to members that are null (including objects as members)... If a member is NULL can you not return it? int get_bar(void) { return bar; // Would this crash if bar is NULL? } // Should I be doing this instead: int get_bar(void) { if(bar != NULL) return bar; else return NULL; } I just glanced at your post though so I'm not sure I fully grasped it. I'm thinking maybe it is possible for that to work with primitive types. If so what if you tried to return a NULL object? myOBJECT *get_object(void) { return object; // Will this crash when object is NULL? } // Should I do this: myOBJECT *get_object(void) { if(object != NULL) return object; else return NULL; }
-- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Zaphos
Member #1,468
August 2001
|
Quote: or just tell me what could cause an "access violations" exception. I thought maybe it was related to the public, private, and protected keywords so to rule that out I put everything public temporarily... The public, private and protected keywords are enforced at compile time, not at run time: they may cause your program to fail to compile, but they should not cause it to crash. MSVC should have a debugger built in -- try running the program with the debugger. Then it should halt execution on the error and tell you where in the code it's happening.
|
Indeterminatus
Member #737
November 2000
|
Quote:
int get_bar(void) { return bar; // Would this crash if bar is NULL? }
Hm, judging by your post, bar is not a pointer (but an int). If it is in fact a int*, it would have to be: int get_bar(void) { return *bar; // Argh! Dereferencing null pointer! Bad! } int* get_bar(void) { return bar; // Safe in any case, as there's no dereferenciation. } // However, get_bar() might be NULL, so be careful with its return value.
Quote:
int get_bar(void) { if(bar != NULL) return bar; else return NULL; }
This is not different to just return bar;. With return *bar;, however, it's a completely different story. Same thing applies to non-primitive data types. _______________________________ |
Tobias Dammers
Member #2,604
August 2002
|
Your comments, plus my comments.
Let's review the concept of a pointer. int a = 25; int* b = &a; // initialize b to point to a
b tells you where to find a. Of course this example is trivial, but that's not the point here. So how do situations like the above arise? There are a number of common causes for these so-called "stray pointers". int* a; *a = 27; // a may point to anything, but not to anything valid 2) Returning pointers to local variables. Example: int* foo() { int bar; return &bar; // bar loses focus right after returning, so the pointer is invalid } 3) Not checking against NULL where this would be appropriate. (It is common practice for functions to return NULL on failure; if a function is documented to do so, please check). Example: BITMAP* bmp = load_bitmap("my_image.bmp", NULL); draw_sprite(screen, bmp, 20, 20); // if bmp is NULL, this can crash! 4) Calling class methods on NULL pointers. Example: class foo { protected: int bar; public: int get_bar() { return bar; } }; int main() { foo myfoo = NULL; cout << myfoo->get_bar(); // myfoo is NULL, so this will crash. } 5) Not setting pointers to NULL after freeing their memory. Example: 6) Overflowing buffers. (Not really a stray pointer example, but still a common cause for an access violation.) Example: 7) Passing NULL to a function that doesn't expect it. Early versions of allegro's destroy_bitmap() had this problem IIRC. --- |
bamccaig
Member #7,536
July 2006
|
Intended Output: x=5 and *y=5 EDIT (Keep in mind I'm not very experienced at this so the above code likely doesn't work at all. Some of it is right, but some parts are not.) Thanks, guys. I couldn't remember the details of pointers and objects in C++, but this thread refreshed it a bit. EDIT And I just stumbed on my problem. I wrote this code late with work in the morning weighing on my shoulders. I was enjoying the coding and didn't want to have to stop. I wanted to get as much done as possible so I was rushing. The tutorial creates a "bounding box" for collision detection using the top left corner position of the bitmap for the top and left edge of the bounding box. It also uses the width and height of the bitmap to get the right and bottom edge of the bounding box. It was on my mind to make sure all of these values were set before I called update_boundingbox() which sets them, but in my rush I neglected the bitmap . The problem was as follows:
The code has now been changed to this:
I can't guarantee it's the best way (in fact I see improvements to be made already), but it's mostly a place to start to get back into it... The program is currently running 'til close. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Tobias Dammers
Member #2,604
August 2002
|
Let me see. You can compare pointers to phone numbers: Now, storing a value (any value) in a pointer is the same as writing down a phone number on a rolodex. Nothing bad happens when you write down a phone number that doesn't exist. But if you try to call it, you will get an error message (segfault). The problem is that you cannot see from the phone number alone whether it's valid or not. On a rolodex card, you might use a '?', or a blank sheet - with pointers, we use the value NULL. --- |
bamccaig
Member #7,536
July 2006
|
Thanks again, Tobias. I think I understand malloc()/free() now. My next question is about new/delete. In my program, I'm instanciating classes with the new operator: PLAYER *objPlayer = new PLAYER(0, 0); SHIP *objShip = new SHIP(0, 0); I'm not sure the right way to clean up the memory so I wanted to check with you. I'm not using malloc() to allocate their memory (at least not directly???), so will free() work to deallocate/release the memory? Also the PLAYER and SHIP classes have pointers as members so I assumed I had to write a destructor to free that memory. Those members are also instanciated using the new operator. What I currently am doing (and not sure if it's actually cleanup up right) is: void OBJECT::~OBJECT() // PLAYER and SHIP inherit from OBJECT. { /* * There is an allegro BITMAP in my class so I deallocate it the * normal way: */ destroy_bitmap(mobjBitmap); // Destroy pointers... delete mobjBoundingBox; delete mobjPosition; } Then at the end of main I do this: // Cleanup pointers. destroy_bitmap(objBuffer); delete objPlayer; delete objShip;
-- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Zaphos
Member #1,468
August 2001
|
Quote: I'm not using malloc() to allocate their memory (at least not directly???), so will free() work to deallocate/release the memory? No -- new and malloc aren't guaranteed to use the same underlying system for allocating memory, so if you allocate with one system and try to free with the other, that will cause undefined behavior. If you use new you must use delete, and if you use malloc you must use free.
|
Tobias Dammers
Member #2,604
August 2002
|
In fact, if you're using C++ and not C, use new and delete whenever you can, which is practically everywhere - don't touch malloc and free at all. Only if you really really have to, and in that case, never mix the two systems. Ever. Of course, when dealing with external C libraries such as allegro, read the manual carefully about how you are supposed to use data structures defined by them. It is very common for such libraries to provide special functions for creating and destroying objects (à la create_bitmap() / destroy_bitmap()). C++ libraries generally assume that you will be using new / delete on the objects they define. BTW, the difference between new / delete and malloc / free is not only that they aren't guaranteed to use the same underlying mechanism. --- |
|