• Welcome to Valhalla Legends Archive.
 

malloc and structs

Started by warz, March 01, 2005, 12:11 AM

Previous topic - Next topic

warz

I have a loop calling the dlopen() function and and setting the returned handle to a struct i have. the thing is, the number of calls to dlopen isn't static. it will change often. so i dont know how many times ill have to declare and instance of my structure for the dlopen() call. i need to use malloc() so i can create however many instances of my struct that i need. malloc only takes size as an argument though. how should i go about using malloc with my struct so after the loop im left with multiple structures?

Maddox

#1
this is pretty basic. if you're going to be iterating through these a lot, you'll probably want to look into making a linked list.

anyways, first you'll need to count up the number of libraries are you are loading initially.

create your array of structs ( num is the number of initial libraries )

int i;
struct mystruct * dlarray = (struct mystruct *)malloc(num * sizeof(struct mystruct));

/* populate it now */
for(i = 0; i < num; i++)
{
         dlarray[i].member = something;
}


when you want to add a library, you'll need to resize your array. ( newnum is the new number of libraries )

struct mystruct * oldarray = dlarray;
struct mystruct * newarray = (struct mystruct *)malloc(newnum * sizeof(struct mystruct));

/* remember num is the old size */
dlarray = (struct mystruct *)memcpy((void *)newarray, (void *)oldarray, num * sizeof(struct mystruct));
free(oldarray);

num = newsize;

/* populate new */
dlarray[num - 1].member = something;
asdf.

Zakath

I recommend using new and delete rather than malloc and free, since their usage is so much simpler. It's up to you, of course, but I find thatmystruct *dlarray = new mystruct[ num ];is easier to work with thanmystruct *dlarray = (mystruct *)malloc( num * sizeof( mystruct ));
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

warz

Ah, this is in C. Sorry, forgot to mention that.

warz

Quote from: Maddox on March 01, 2005, 12:56 AM
this is pretty basic. if you're going to be iterating through these a lot, you'll probably want to look into making a linked list.

anyways, first you'll need to count up the number of libraries are you are loading initially.

create your array of structs ( num is the number of initial libraries )

int i;
struct mystruct * dlarray = (struct mystruct *)malloc(num * sizeof(struct mystruct));

/* populate it now */
for(i = 0; i < num; i++)
{
         dlarray[i].member = something;
}


when you want to add a library, you'll need to resize your array. ( newnum is the new number of libraries )

struct mystruct * oldarray = dlarray;
struct mystruct * newarray = (struct mystruct *)malloc(newnum * sizeof(struct mystruct));

/* remember num is the old size */
dlarray = (struct mystruct *)memcpy((void *)newarray, (void *)oldarray, num * sizeof(struct mystruct));
free(oldarray);

num = newsize;

/* populate new */
dlarray[num - 1].member = something;


Perfect, Maddox. Works great. Thanks, brotha. hehe.

Kp

Maddox's code reflects a C++ user trying to think in C. :)  There's no need to explicitly malloc/free when growing the array, just use realloc(void *old_memory, int new_size);  realloc will then handle the copy/free details for you, leaving you with one memory block of the new size (possibly at a new address) which is guaranteed to have the same contents for the first min(oldsize, newsize) bytes.  C++'s memory allocation operators lack an equivalent call.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Maddox

Quote from: Kp on March 01, 2005, 04:18 PM
Maddox's code reflects a C++ user trying to think in C. :)  There's no need to explicitly malloc/free when growing the array, just use realloc(void *old_memory, int new_size);  realloc will then handle the copy/free details for you, leaving you with one memory block of the new size (possibly at a new address) which is guaranteed to have the same contents for the first min(oldsize, newsize) bytes.  C++'s memory allocation operators lack an equivalent call.

this is true. I'm actually writing some C code right now, so this will come in handy.
asdf.

Zakath

I would say that thinking in C++ isn't such a bad thing :P

C: myfunc( stuff ) int stuff; { /* function body */ }

C++: void myfunc( int stuff ) { /* function body */ }
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

Kp

Quote from: Zakath on March 03, 2005, 06:38 PM
I would say that thinking in C++ isn't such a bad thing :P

C: myfunc( stuff ) int stuff; { /* function body */ }

C++: void myfunc( int stuff ) { /* function body */ }

That's not at all relevant, and the latter style has been supported (and afaik encouraged) by gcc for ages.  Anyway, thinking in C++ is a bad idea when you're trying to write C code, since there's some C idioms that got lost in C++ (for instance, the idea of using realloc, which got lost because nobody thought to put a reallocation operator in C++).  You can make something that works, but it'll generally be less elegant.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!