11 Mar, 2009, Keberus wrote in the 1st comment:
Votes: 0
Is it okay to use a C++ list type iterator in a structure data type? I am trying to implement a custom skill system and my struct char_data has this line:

list < custom_skill *> cskills;


Which I believe is how I define a list for the custom skills. Problem is that it doesn't seem to be initialized. So I tried putting in a reference in some test code that calls

ch->cskills.clear();


But doing so causes a seg fault. So my real question is, if I want to use iterators does the parent have to be a class instead of a structure? I'm just not sure if it has to do with the fact that I am calling the CREATE macro, which uses calloc, instead of using new to define the parent class. Anyways, any insight would be useful.


Thanks in advance,
KeB
11 Mar, 2009, Davion wrote in the 2nd comment:
Votes: 0
Keberus said:
I'm just not sure if it has to do with the fact that I am calling the CREATE macro, which uses calloc, instead of using new to define the parent class.


That's exactly your problem. Always make sure to call new/delete on structures containing C++ entities. The *alloc calls don't correctly initialize anything from the STL.
11 Mar, 2009, Tyche wrote in the 3rd comment:
Votes: 0
#include <list>
using namespace std;

struct foo {
list<int> lst;
};

int main() {
// create
struct foo * x = (foo*) calloc(1, sizeof(struct foo));

// initialize
new (&x->lst) list<int>;
x->lst.clear();

// destroy
x->lst.~list<int>();
free(x);

}


Bring on the flames.
11 Mar, 2009, quixadhal wrote in the 4th comment:
Votes: 0
That reminds me of watching people make ice sculptures using chainsaws. The end result is lovely, but there are bits flying everywhere and you're sure a whole chunk is bound to get lopped off somewhere….. :)
11 Mar, 2009, Keberus wrote in the 5th comment:
Votes: 0
Quote
That's exactly your problem. Always make sure to call new/delete on structures containing C++ entities. The *alloc calls don't correctly initialize anything from the STL.


So, I take it that I sould use the double linked list C style until/if I start using new to create the CHAR_DATA calls.

Thanks guys,
KeB
11 Mar, 2009, Zeno wrote in the 6th comment:
Votes: 0
I've been working with AFKMUD recently which uses list type iterators. Could look over that.
11 Mar, 2009, David Haley wrote in the 7th comment:
Votes: 0
If you want to use any C++ object, you need to initialize the object. It is very rare that initialization means zeroing out the memory.

It's not so hard to use new/delete, but it is work that you'd have to do.

You could always initialize things like Tyche said, but that's kind of nasty… :wink:
11 Mar, 2009, Guest wrote in the 8th comment:
Votes: 0
It can't really be any nastier than this:

class mud_channel
{
private:
mud_channel( const mud_channel & m );
mud_channel & operator=( const mud_channel & );

public:
mud_channel( );
~mud_channel( );

bitset < CHAN_MAXFLAG > flags;
string name;
string colorname;
char *history[MAX_CHANHISTORY][2]; /* Not saved */
time_t htime[MAX_CHANHISTORY]; /* Not saved *//* Xorith */
int hlevel[MAX_CHANHISTORY]; /* Not saved */
int hinvis[MAX_CHANHISTORY]; /* Not saved */
int level;
int type;
};

void init_memory( void *start, void *end, unsigned int size )
{
memset( start, 0, ( int )( ( char * )end + size - ( char * )start ) );
}

mud_channel::mud_channel( )
{
init_memory( &history, &type, sizeof( type ) );
}

channel = new mud_channel;


I don't even remember where I picked up the init_memory thing from, but it works and causes no issues, so long as one does not forget how the class is setup. Adding another C++ element would have to go above the history member in order to work. Adding it below the existing stuff would result in a crash.
11 Mar, 2009, David Haley wrote in the 9th comment:
Votes: 0
Woah now. That's just plain evil on so many levels :lol:
11 Mar, 2009, Guest wrote in the 10th comment:
Votes: 0
Evil, yes, but who says in order for code to work that it has to be good :)
0.0/10