19 Aug, 2009, JohnnyStarr wrote in the 1st comment:
Votes: 0
I have been adding in c++ features to my project, and have found that I am getting
some unexpected SEG-FAULTS. When I use gdb to figure it out I dont really know what
went wrong. For instance, I added in QUEST_DATA class, which I create with the 'new' keyword, when adding this to a ch it works fine, the compiler detects no errors, but it bombs, and I dont really know why. The object isn't null, and the ch isn't null. Is it possibly because the ch is created with alloc_perm and the quest is created with new?

If that isn't the issue, then i need to figure out a way to error trap more effectively. I know c++ has a 'try' statement, how might that be used in the following context?

here is an example of my code, keep in mind I'm just starting off by creating 1 quest right now.
in load function:
QUEST_DATA* q = new QUEST_DATA;
ch->quests = q; // ch->quests is just a C style linked list for testing

constructor in quest.cpp
Quest::Quest() {
name = "Fake Quest";
desc = "This is a fake quest, its really fake";
next = NULL; // just a quick example
}


The error is not on the assignment of ch->quests = q;
The crash is in the ch->view_quests() method:

CHAR_DATA::view_quests(void) {
QUEST_DATA* q;
for(q = quests; q != NULL; q = q->next)
printf("%s, %s", q->name, q->desc);
// printf was added in character.cpp to avoid printf_to_char
}
19 Aug, 2009, tphegley wrote in the 2nd comment:
Votes: 0
A good thing to show would be gdb output.
19 Aug, 2009, quixadhal wrote in the 3rd comment:
Votes: 0
Assuming your class uses std::string for the string members, printf can't deal with that. To use the printf family of C functions, you have to convert the strings to character arrays.

printf("%s %s", q->name.cstr(), q->desc.cstr());

OTOH, if you're using char *'s for members, assigning via '=' is not really what you want (although it shouldn't crash… at that point). In that case, you'd want to be using strdup() and your destructor function would have to use free().
19 Aug, 2009, David Haley wrote in the 4th comment:
Votes: 0
Furthermore,
CHAR_DATA::view_quests(void) {
QUEST_DATA* q;
for(q = quests; q != NULL; q = q->next)
printf("%s, %s", q->name, q->desc);
// printf was added in character.cpp to avoid printf_to_char
}

In this code, if CHAR_DATA doesn't initialize 'quests' to NULL, you'll be walking over bogus memory.

That said, the best thing to do is to use gdb as tphegley suggested. That will tell you exactly where it's crashing.
19 Aug, 2009, JohnnyStarr wrote in the 5th comment:
Votes: 0
The code I wrote in my post was off of memory here at work, so its not exact. I did in fact use q->name.c_str() to convert. I think what David said about the quests being asigned to NULL is it.
I was assuming that ch->quests = q; would be enough?
19 Aug, 2009, David Haley wrote in the 6th comment:
Votes: 0
Quote
I was assuming that ch->quests = q; would be enough?

That's fine for after you actually assign the quest, but until you do, ch->quests is just bogus memory unless initialized.
19 Aug, 2009, JohnnyStarr wrote in the 7th comment:
Votes: 0
Ok then, do you think it's better to use gdb on the core dump in this case or the actual executable?
Right now I'm using Cygwin and it dums a stackdump and I havent gotten the 'dumper' to make it
dump a core file yet. Also, when it comes to breakpoints with c++ when i type next it seems to go into what
i can only assume is the STL and its very hard to figure out whats what. Any suggestions on this?
19 Aug, 2009, David Haley wrote in the 8th comment:
Votes: 0
In general I prefer to run the process in gdb and reproduce the crash. I use the core dump when I don't know how to reproduce the crash.

It's possible to configure gdb to skip certain files, I think, but I never bothered to be honest. Usually seeing the backtrace and poking at a couple of variables is enough for me to see what happened.

If you haven't already, I strongly recommend this guide to gdb (by Nick Gammon).
20 Aug, 2009, JohnnyStarr wrote in the 9th comment:
Votes: 0
When using a destructor, do you have to 'delete' each std::string in the class?
Or will setting the value to NULL be fine? Or will just deleting the object clear it out?

eg:
~Quest() {
name = NULL;

OR

delete(name);

}
20 Aug, 2009, David Haley wrote in the 10th comment:
Votes: 0
You cannot 'delete' things that were not allocated on the heap; they simply die when they fall out of scope (or the object containing them is destructed). You must explicitly delete anything that you allocate on the heap; setting to NULL will do absolutely nothing other than set the pointer to NULL. (A pointer is just a reference to a chunk of memory, it has no such smarts.)

So the short answer is that if name is a pointer, you must delete it, but if it is not a pointer, its destructor will be automatically called when its enclosing object's destructor is called.
20 Aug, 2009, JohnnyStarr wrote in the 11th comment:
Votes: 0
David Haley said:
So the short answer is that if name is a pointer, you must delete it, but if it is not a pointer, its destructor will be automatically called when its enclosing object's destructor is called.

Say you had a char *string in the class? Because std::string is an object and not a pointer, does that mean you have to use free(my_c_string)?
20 Aug, 2009, KaVir wrote in the 12th comment:
Votes: 0
staryavsky said:
Say you had a char *string in the class? Because std::string is an object and not a pointer, does that mean you have to use free(my_c_string)?

If you allocated it with strdup() then you should free it with free(), yes, and that can get confusing. Best to stick with new and delete, so you don't have to worry about how the memory was allocated.
0.0/12