Thanks! I don't mean by the way to sound like I'm demanding anything - but I do want to move so that I can develop a new release (including fixing the existing bugs)
In the mean time, I am going to explore some additional possibilities; I think I'll start with magic wands. What I want to do is make an item and presumably edit Creature::give_weapon() to prevent a weapon from being equip-able without certain criteria being met (in this case, the wielder having Magic skill).
I think I fixed yer code, the fix is in the thread where ya posted it:
http://www.bay12forums.com/smf/index.php?topic=134139.msg5649781#msg5649781So that oughta end all this segfault business. Basically the point is, use references instead of pointers, and make the functions static instead of const. References are safer than pointers since they can't be null and also the data will be stored in-place where the variable is declared in the function, rather than allocated on the heap using the "new" operator.
Secondarily, makin' the functions static rather than const means... well this'll take multiple sentences. By default functions in a class are "methods" that are attached to a specific object of that class, a specific instance, for which all the member variables are defined as well as the "this" operator. A const function which has the word "const" at the end of the function declaration is a class method that promises not to alter any of the member variables of the current instance of the class (the current object, "this"). A static function is a function belonging to a class but which does not belong to any object of that class and can be called by using the class namespace and the :: operator, without even using an object of that class, and a static function is not tied to any instance of the class.
So a local variable declared in a static function will only be declared once for the entire class (for instance the local variable naked in armor_none() is only declared once in the Creature class), whereas a local variable declared in a non-static member function, including a const function, is declared separately for every single object of that class.
Now, each of those objects of the Weapon class you created in weapon_magic(), weapon_powers(), and weapon_suit() was created on the heap using the "new" operator rather than created locally using a reference (meaning, you are obligated to delete them later on, every call to "new" must be paired with a call to "delete" in C++ memory management and you failed to do this), and moreover you were creating a new object of the Weapon class for each of those 3 functions for every single object of the Creature class rather than just doing it once for the entire Creature class by using a static function. In the best case scenario this type of coding would lead to a memory leak but not crash the program and in the worst case scenario it would case a segfault.
It caused a segfault.
Anyway I gave ya the code to fix it... just try to remember what a static member function for a class is, and try to remember the difference between a reference and a pointer, and try to remember how calls to the "new" operator need to be paired with calls to the "delete" operator in C++ memory management. "New" is called right before you need to use something the first time and "delete" is called once you're done with it and don't need it anymore. Using the "new" and "delete" operators along with pointers without bein' too careful, and without knowin' how often a function will be called and how often the variable'll get declared, that's a bit of a pickle.
Another little problem: the variables are declared as static in the function. That means the first time the function gets called those variables get initialized to that value, but then they stay at that value and don't get set, future times the function is called. But if ya declare a static variable in a non-static member function, like you did, what does THAT do?
... thinking ...
I don't even know what that does! I tried thinkin' bout it and even with my C++ knowledge it makes my head hurt! But what it does is probably not anything good. If you're declaring static variables, the function you declare 'em in had best be static too! And if the function is NOT a member of a class then that means it's static by definition... a static function means a function not tied to a specific object of a class.
Wow I reckon this C++ sure can be confusin' at times! Now if ya noticed how I implemented music in recent revisions, I declared a class called MusicClass, which only has one object, declared in both game.cpp as a global variable in that file and externs.h as a global variable that is external, and it isn't a pointer to an object of that class that must be created with "new" and destroyed with "delete", but rather, an object of that class created directly without any pointer stuff (so it's sorta like a reference, in that it can't be NULL, except for the fact that it isn't a reference, it's even simpler, it's just an ordinary variable of that class). This means no memory management mumbo jumbo and no chance of segfaults or memory leaks or any of that nonsense.
Now there are plenty of times pointers ARE needed. Like if you have an array of objects your array is typically an array of pointers to objects. Unlike references, you are allowed to set pointers to equal NULL, and unlike references, you can change what they point to, whenever you feel like it, in fact you have a great deal of freedom what to do with pointers, which is a double-edged sword. While pointers are quite versatile indeed they allow you to do all sorts of Very Bad Things that are likely to crash your program. The main reason C++ is faster than Java is pointers and having the programmer take care of memory management instead of having automatic garbage collection. The main reason Java is safer than C++ and less likely to crash is Java doesn't have pointers and it does automatic garbage collection instead of having the programmer do memory management.
Anyway, if ya keep using C++ you're gonna have to get used to this sorta stuff... it's what makes C++ so fast but also so easy to make programs that crash. By usin' my solution with references instead of pointers and avoiding calling "new" and making the functions static, you're takin' advantage of some C++ features designed to make things easier and avoid stuff crashin' too often. That's the whole reason C++ introduced references, which weren't in ANSI C... to prevent crashes and segfaults. Most of the time when yer havin' segfaults you can fix it by thinkin' "Hmm can I do this usin' references instead of pointers?" and then doin' it using references instead of pointers. And if ya can't do it usin' references instead of pointers, well then be sure to do your memory management perfectly and not dereference any pointer that's uninitialized or NULL... that takes a bit more work.
The current code for Liberal Crime Squad is a mishmash of all different coding styles with some stuff using references and other stuff using pointers, some stuff using object-oriented C++ style code and other stuff using old-fashioned low-level C style code. I've been gradually moving the code in the direction of object-oriented C++ style code that uses references instead of pointers but quite gradually indeed so there's still a TON of pointers in the code... in some cases pointers are just a more efficient way of doing things because you can change their values and they are allowed to be NULL and sometimes you actually WANT them to be NULL, in order to symbolize the idea of an object not existing, something you can't do with references.
Now if ya don't like this sorta stuff I reckon yer best off quittin' C++ and switchin' to Java or somethin' else like that, some language that doesn't have pointers, does all the memory management for you automatically, and thus doesn't have segfaults. There's a bunch of other high-level languages besides Java that also take care of all that stuff for ya and make things safe so that segfaults are pretty much impossible. But if you're programming in C or C++ than this sorta thing is just something you have to get used to, it comes with the territory of using language that has low-level features. C is a low-level language but C++ is a multi-level language that can be both low-level AND high-level depending on how you use it. That's part of what makes C++ so insanely versatile... and I really would call C++'s versatile design somewhat insane. Another thing about C++ that is insane is all the parts of it that aren't standardized, even if your compiler follows the official standard, things that are so obvious as things that should be standardized, like how many bits of data the "int" type takes up. Usually it's 32 but it could be 16 or 64 on some compilers and systems, and I think there's even some strange compilers for strange systems where it's 128. That type of stuff is why although C++ is a cross-platform language supported by almost all platforms, making C++ programs actually WORK on different platforms is often quite a pain... plus there's also the big-endian vs. little-endian problem in C and C++, something that really high-order languages hide from you but C and C++ don't. There are some places in the code of Liberal Crime Squad where a number is shifted right 1 bit to divide it by 2, or shifted right 2 bits to divide it by 4... this is endian-dependent and won't work on all platforms, since on platforms with opposite endianness, you need to switch right sifts and left shifts around.
So basically to summarize, anyone programming in C or C++ is just askin' fer trouble from their computer, just askin' for strange odd bugs to occur that they have a hard time replicating, and all sorts of weirdness. But that's also why C and C++ are so popular, since they MAKE you be a good programmer. In other languages that are higher-order, like Java, the compiler will catch almost all your mistakes and tell you what you did wrong, and treat you like a little kid. But C and C++ is grownup stuff, it's for people who aren't afraid of bugs and want to become good programmers. It's the same reason I'm still nostalgic for DOS... DOS was an operating system for adults, not kids, it was an operating system for people who knew what they were doing. DOS let any program do anything at all it wanted with no limitations... access any location in memory, directly communicate with any hardware device... you name it. UNIX-based operating systems and Windows NT-based operating systems, on the other hand, limit the rights and abilities of all programs, granting them some abilities but not others, and not allowing them to communicate with hardware unless they're in kernel mode, and not letting them access memory outside what is allocated to them or any shared memory they have permissions for. Using C or C++ is like using DOS... you are able to do more things and have more control, and not be as limited. Of course I only have this DOS nostalgia because I wrote programs for DOS back when I was a kid and enjoyed how I could write things to communicate directly with hardware and do all sorts of neat stuff that isn't allowed at all in modern operating systems that have security and limit the rights of user-mode programs. The great downfall of the DOS architecture is that a malicious or badly-designed program can destroy everything, typically requiring you to restart the computer if a program crashes, but a truly malicious program in DOS can do any evil thing it wants with no way to protect against this. This is also true of both Windows 3.1 and earlier, and Windows 95/98/ME, which are all DOS-based and share these same architectural weaknesses (thus causing the ubiquitous Blue Screen of Death of those Windows versions, as well as the constant memory leak in those Windows versions that would require you to restart the computer every few days to keep from running out of memory, since if you ran a program that had a memory leak in it, that memory would remain allocated and not be usable after the program terminated, quite an immense flaw indeed).