Variable arguments func (how to)

G

Grey Alien

My C is a bit rusty, after spending several years in the C++ garden. I
want to write a func like :

long AllocStruts(MyStruct s1, ...)
{
long ret = -1 ;

/*allocate memory for all structs passed in*/
/* If an allocation fails, free all previously allocated memory and
return error */

return ret ; /* 0 == success, else eror
}


How may I implement such a func?.
 
A

Army1987

Grey Alien said:
My C is a bit rusty, after spending several years in the C++ garden. I want to write a func like :

long AllocStruts(MyStruct s1, ...)
You need to somehow know how many argument there are, and what
their types are.
{
long ret = -1 ;

/*allocate memory for all structs passed in*/
/* If an allocation fails, free all previously allocated memory and return error */

return ret ; /* 0 == success, else eror
Why use long? Will you need more than 65534 different possible
error codes, or what?
}


How may I implement such a func?.
Look up for <stdarg.h>
 
C

Christopher Benson-Manica

Grey Alien said:
long AllocStruts(MyStruct s1, ...)

First of all, this signature implies that 1) space has already been
allocated for the arguments (not what you want), and 2) the structs
are being passed by value (not what you want).
{
long ret = -1 ;
/*allocate memory for all structs passed in*/
/* If an allocation fails, free all previously allocated memory and
return error */
return ret ; /* 0 == success, else eror
}
How may I implement such a func?.

I'm assuming that this isn't homework (apologies to the regulars if it
is); consider the following (hopefully correct) program:

/* Begin test.c */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

struct foo {
char *bar;
};

int alloc_structs( int count, ... ) {
va_list vargs, freeargs;
int idx, jdx;
struct foo **ptr;
va_start( vargs, count );
va_copy( freeargs, vargs );
for( idx=0; idx < count; idx++ ) {
ptr=va_arg( vargs, struct foo ** );
*ptr=malloc( sizeof(struct foo) );
if( !*ptr ) {
for( jdx=0; jdx <= idx; jdx++ ) {
free( va_arg(freeargs,struct foo **) );
}
return 1; /* failure */
}
}
return 0; /* success */
}

int main(void) {
struct foo *baz;
struct foo *qux;
alloc_structs( 2, &baz, &qux );
baz->bar="foo";
qux->bar="bar";
printf( "%s %s\n", baz->bar, qux->bar );
return 0;
}

/* End test.c */
 
C

Christopher Benson-Manica

Christopher Benson-Manica said:
I'm assuming that this isn't homework (apologies to the regulars if it
is); consider the following (hopefully correct) program:
(snipped)

Oops, it's not correct in at least one way, but at least my bases are
covered if it IS homework. (Inserting invocations to va_end as
appropriate is left as a minor exercise for the reader.)
 
G

Grey Alien

Christopher said:
First of all, this signature implies that 1) space has already been
allocated for the arguments (not what you want), and 2) the structs
are being passed by value (not what you want).

True. I made a mistake. It should be taking a ptr to the struct
I'm assuming that this isn't homework (apologies to the regulars if it
is); consider the following (hopefully correct) program:

No it isn't :) I'm working with some *OLD* C code which I have to
interface to from C++
/* Begin test.c */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

struct foo {
char *bar;
};

int alloc_structs( int count, ... ) {
va_list vargs, freeargs;
int idx, jdx;
struct foo **ptr;
va_start( vargs, count );
va_copy( freeargs, vargs );
for( idx=0; idx < count; idx++ ) {
ptr=va_arg( vargs, struct foo ** );
*ptr=malloc( sizeof(struct foo) );
if( !*ptr ) {
for( jdx=0; jdx <= idx; jdx++ ) {
free( va_arg(freeargs,struct foo **) );
}
return 1; /* failure */
}
}
return 0; /* success */
}

int main(void) {
struct foo *baz;
struct foo *qux;
alloc_structs( 2, &baz, &qux );
baz->bar="foo";
qux->bar="bar";
printf( "%s %s\n", baz->bar, qux->bar );
return 0;
}

/* End test.c */

Thanks
 
C

Christopher Benson-Manica

Christopher Benson-Manica said:
for( jdx=0; jdx <= idx; jdx++ ) {
free( va_arg(freeargs,struct foo **) );
}

Yikes. That free() call should obviously be

free( *va_arg(freeargs,struct foo **) );

Hopefully the code I'm being *paid* to write today will not be so
egregiously wrong. *sigh*
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top