Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #18885 > unrolled thread
| Started by | Martin De Kauwe <mdekauwe@gmail.com> |
|---|---|
| First post | 2012-03-19 19:32 -0700 |
| Last post | 2012-03-20 07:27 -0700 |
| Articles | 8 — 5 participants |
Back to article view | Back to comp.lang.c
How to write own function to allocation a set of structures? Martin De Kauwe <mdekauwe@gmail.com> - 2012-03-19 19:32 -0700
Re: How to write own function to allocation a set of structures? Ian Collins <ian-news@hotmail.com> - 2012-03-20 15:50 +1300
Re: How to write own function to allocation a set of structures? Barry Schwarz <schwarzb@dqel.com> - 2012-03-19 20:14 -0700
Re: How to write own function to allocation a set of structures? Martin De Kauwe <mdekauwe@gmail.com> - 2012-03-19 23:58 -0700
Re: How to write own function to allocation a set of structures? Ian Collins <ian-news@hotmail.com> - 2012-03-20 21:13 +1300
Re: How to write own function to allocation a set of structures? Martin De Kauwe <mdekauwe@gmail.com> - 2012-03-20 02:32 -0700
Re: How to write own function to allocation a set of structures? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-20 13:06 +0000
Re: How to write own function to allocation a set of structures? ImpalerCore <jadill33@gmail.com> - 2012-03-20 07:27 -0700
| From | Martin De Kauwe <mdekauwe@gmail.com> |
|---|---|
| Date | 2012-03-19 19:32 -0700 |
| Subject | How to write own function to allocation a set of structures? |
| Message-ID | <354bb461-708b-4ce5-99ad-ab0b37872797@x10g2000pbi.googlegroups.com> |
Hi,
I currently allocate a series of structures...
in the .h file
typedef struct {
FILE *in_fp;
etc....
} control_struct;
then in the main func:
control_struct *ctrl;
if ((ctrl = malloc(sizeof(control_struct))) == NULL) {
fprintf(stderr, "control structure: Not allocated enough memory
\n");
exit(EXIT_FAILURE);
}
I would like to write my own generic function to take the malloc
section to tidy up the code (as I have a number of structures to
allocate), i.e. so instead in the main I would have something like
allocate_structure(&ctrl);
and
void allocate_structure(structure *s) {
if ((s = malloc(sizeof(structure))) == NULL) {
fprintf(stderr, "Structure: Not allocated enough memory\n");
exit(EXIT_FAILURE);
}
}
But I am not sure how to pass the structure when it is unallocated,
i.e. how to set up the function declarations.
Any assistance would be very helpful
thanks.
[toc] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-03-20 15:50 +1300 |
| Message-ID | <9sq9k5FuerU3@mid.individual.net> |
| In reply to | #18885 |
On 03/20/12 03:32 PM, Martin De Kauwe wrote:
> Hi,
>
> I currently allocate a series of structures...
>
> in the .h file
>
> typedef struct {
> FILE *in_fp;
> etc....
> } control_struct;
>
> then in the main func:
>
> control_struct *ctrl;
> if ((ctrl = malloc(sizeof(control_struct))) == NULL) {
> fprintf(stderr, "control structure: Not allocated enough memory
> \n");
> exit(EXIT_FAILURE);
> }
>
> I would like to write my own generic function to take the malloc
> section to tidy up the code (as I have a number of structures to
> allocate), i.e. so instead in the main I would have something like
>
> allocate_structure(&ctrl);
>
> and
>
> void allocate_structure(structure *s) {
> if ((s = malloc(sizeof(structure))) == NULL) {
> fprintf(stderr, "Structure: Not allocated enough memory\n");
> exit(EXIT_FAILURE);
> }
> }
>
> But I am not sure how to pass the structure when it is unallocated,
> i.e. how to set up the function declarations.
Either return the value allocated, or pass a pointer to the pointer:
structure* allocate_structure()
{
structure* s = malloc(sizeof *s);
//error check
return s;
}
Or
void allocate_structure( structure** s )
{
*s = malloc(sizeof *s);
//error check
}
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2012-03-19 20:14 -0700 |
| Message-ID | <rmsfm7p8u92iun6n37sn6m6qp7ihabvnl3@4ax.com> |
| In reply to | #18885 |
Is your function going to allocate space for exactly one object of the
same structure type each time? If so, Ian's suggestions should work
just fine.
If it is a variable quantity but always the same structure type, then
pass the quantity as a parameter, use it in the call to malloc, and
still follow Ian's suggestions.
If the structure type also varies, then something like
void * alloc_struct(size_t struct_size, int quantity)
{
void *ptr = malloc(struct_size * quantity);
if (!ptr)
{
/* your error logic here */
}
return ptr;
}
could be called with code like
struct1_ptr = alloc_struct(sizeof(struct1), 5);
struct2_ptr = alloc_struct(sizeof(struct2), 8);
On Mon, 19 Mar 2012 19:32:28 -0700 (PDT), Martin De Kauwe
<mdekauwe@gmail.com> wrote:
>Hi,
>
>I currently allocate a series of structures...
>
>in the .h file
>
>typedef struct {
> FILE *in_fp;
> etc....
>} control_struct;
>
>then in the main func:
>
>control_struct *ctrl;
>if ((ctrl = malloc(sizeof(control_struct))) == NULL) {
> fprintf(stderr, "control structure: Not allocated enough memory
>\n");
> exit(EXIT_FAILURE);
>}
>
>I would like to write my own generic function to take the malloc
>section to tidy up the code (as I have a number of structures to
>allocate), i.e. so instead in the main I would have something like
>
>allocate_structure(&ctrl);
>
>and
>
>void allocate_structure(structure *s) {
> if ((s = malloc(sizeof(structure))) == NULL) {
> fprintf(stderr, "Structure: Not allocated enough memory\n");
> exit(EXIT_FAILURE);
> }
>}
>
>But I am not sure how to pass the structure when it is unallocated,
>i.e. how to set up the function declarations.
>
>Any assistance would be very helpful
>
>thanks.
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Martin De Kauwe <mdekauwe@gmail.com> |
|---|---|
| Date | 2012-03-19 23:58 -0700 |
| Message-ID | <8223ddb2-04c4-435e-9e6a-4c56c3f0cba9@vy8g2000pbc.googlegroups.com> |
| In reply to | #18889 |
Sorry I am not sure I quite sure I followed that. I do have variable
length structures, e.g. some are X parameters long, some are a set of
controlling flags. I tried implementing the first example, but I am
clearly misunderstanding how to do this.
in the .h file
typedef struct {
FILE *ifp;
int num_days;
etc...
} control_struct;
void allocate_structure(structure **);
in the .c file
int main(int argc, char **argv)
{
/* Allocate all structures */
control_struct *ctrl;
allocate_structure(&ctrl);
etc...
void allocate_structure(structure **s)
{
if ((*s = malloc(sizeof(*s))) == NULL) {
fprintf(stderr, "some msg\n");
exit(EXIT_FAILURE);
}
}
it says it doesn't know what 'structure' is when it compiles. I must
be misunderstanding as this is what I didn't get, i.e. how to pass the
structure, what you call it when you pass it to the function.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-03-20 21:13 +1300 |
| Message-ID | <9sqshlFc6rU1@mid.individual.net> |
| In reply to | #18892 |
On 03/20/12 07:58 PM, Martin De Kauwe wrote:
> Sorry I am not sure I quite sure I followed that. I do have variable
> length structures, e.g. some are X parameters long, some are a set of
> controlling flags. I tried implementing the first example, but I am
> clearly misunderstanding how to do this.
>
> in the .h file
>
> typedef struct {
> FILE *ifp;
> int num_days;
> etc...
> } control_struct;
>
> void allocate_structure(structure **);
>
> in the .c file
>
> int main(int argc, char **argv)
> {
> /* Allocate all structures */
> control_struct *ctrl;
> allocate_structure(&ctrl);
> etc...
>
> void allocate_structure(structure **s)
> {
> if ((*s = malloc(sizeof(*s))) == NULL) {
> fprintf(stderr, "some msg\n");
> exit(EXIT_FAILURE);
> }
>
> }
>
> it says it doesn't know what 'structure' is when it compiles. I must
> be misunderstanding as this is what I didn't get, i.e. how to pass the
> structure, what you call it when you pass it to the function.
It sounds like you are looking for C++ style templates, which C lacks.
In C, you would have to resort to a macro. Something like
#define ALLOCATE_STRUCTURE( s ) \
if ((s = malloc(sizeof(*s))) == NULL) { \
fprintf(stderr, "some msg\n"); \
exit(EXIT_FAILURE); } \
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Martin De Kauwe <mdekauwe@gmail.com> |
|---|---|
| Date | 2012-03-20 02:32 -0700 |
| Message-ID | <d131016a-eacf-45c4-b7c5-2b81a3372ec8@ow8g2000pbc.googlegroups.com> |
| In reply to | #18893 |
I have never used c++ so i am not sure what a c++ style template is, but perhaps it is because I have been using a lot of python recently. What you suggested works fine. Ideally what I was trying to do was move all the structure allocation into a function so the main function read a little cleaner. Your suggestion certainly helps, thanks.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-03-20 13:06 +0000 |
| Message-ID | <0.c7863358bf1d9ffca8ac.20120320130601GMT.874ntje81y.fsf@bsb.me.uk> |
| In reply to | #18892 |
Martin De Kauwe <mdekauwe@gmail.com> writes:
> Sorry I am not sure I quite sure I followed that. I do have variable
> length structures, e.g. some are X parameters long, some are a set of
> controlling flags. I tried implementing the first example, but I am
> clearly misunderstanding how to do this.
>
> in the .h file
>
> typedef struct {
> FILE *ifp;
> int num_days;
> etc...
> } control_struct;
>
> void allocate_structure(structure **);
>
> in the .c file
>
> int main(int argc, char **argv)
> {
> /* Allocate all structures */
> control_struct *ctrl;
> allocate_structure(&ctrl);
> etc...
>
> void allocate_structure(structure **s)
> {
> if ((*s = malloc(sizeof(*s))) == NULL) {
Note: type here. Corrected in my version below.
> fprintf(stderr, "some msg\n");
> exit(EXIT_FAILURE);
> }
>
> }
>
> it says it doesn't know what 'structure' is when it compiles.
On the surface it looks like you simply did not update Ian's example to use
your types. He wrote "void allocate_structure(structure **s)" but that
was a generic example. You'd have to use your own type:
void allocate_structure(constrol_struct **s)
{
if ((*s = malloc(sizeof **s)) == NULL) {
fprintf(stderr, "some msg\n");
exit(EXIT_FAILURE);
}
}
Note the correction to sizeof **s rather than sizeof *s.
> be misunderstanding as this is what I didn't get, i.e. how to pass the
> structure, what you call it when you pass it to the function.
Out of interest, why do you want to it this way? I usually prefer the
functional "return the pointer" style if it is available,
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | ImpalerCore <jadill33@gmail.com> |
|---|---|
| Date | 2012-03-20 07:27 -0700 |
| Message-ID | <976bdf97-4076-4fac-af65-ab5fb105b5b2@v2g2000vbx.googlegroups.com> |
| In reply to | #18885 |
On Mar 19, 10:32 pm, Martin De Kauwe <mdeka...@gmail.com> wrote:
> Hi,
>
> I currently allocate a series of structures...
>
> in the .h file
>
> typedef struct {
> FILE *in_fp;
> etc....
>
> } control_struct;
>
> then in the main func:
>
> control_struct *ctrl;
> if ((ctrl = malloc(sizeof(control_struct))) == NULL) {
> fprintf(stderr, "control structure: Not allocated enough memory
> \n");
> exit(EXIT_FAILURE);
>
> }
>
> I would like to write my own generic function to take the malloc
> section to tidy up the code (as I have a number of structures to
> allocate), i.e. so instead in the main I would have something like
>
> allocate_structure(&ctrl);
>
> and
>
> void allocate_structure(structure *s) {
> if ((s = malloc(sizeof(structure))) == NULL) {
> fprintf(stderr, "Structure: Not allocated enough memory\n");
> exit(EXIT_FAILURE);
> }
>
> }
>
> But I am not sure how to pass the structure when it is unallocated,
> i.e. how to set up the function declarations.
>
> Any assistance would be very helpful
I prefer to use the same style as malloc to get an allocated block of
memory. In the same way, I also prefer to keep error handling out of
the allocation function, relying on checking NULL to determine if
there was an error.
\code
control_struct* cs_alloc( void )
{
control_struct* cs = NULL;
cs = malloc( sizeof (control_struct) );
if ( cs ) {
/* Any necessary initialization in here. */
}
return cs;
}
\endcode
You can change the style of allocation by writing a macro that takes a
type parameter instead of a size parameter.
\code
/*!
* \brief Allocate an array of objects by their type.
* \param type The object type.
* \param n The number of objects to allocate.
* \return A pointer to the allocated memory, or \c NULL if the
* requested allocation failed.
*/
#define c_new( type, n ) (malloc( sizeof (type) * (size_t)(n) ))
\endcode
This is just an allocation style that accents the 'type' rather than
the type neutral 's = malloc(sizeof *s)'. Preferences vary.
As you write more code, you'll find that you develop a particular
style of structured error handling. You can often create a macro that
wraps your style and use that macro everywhere. The bonus is that if
you ever change your style, you often only have to do it in one place,
not everywhere.
\code
/* __func__ is standard C in C99 and higher */
#if !defined(__STDC_VERSION__) /* __STDC_VERSION__ defined in C99 */
# if (defined(__GNUC__) && __GNUC__ >= 2) || defined(_WIN32) ||
defined(__WIN32__)
# define __func__ ((const char*) __FUNCTION__)
# else
# define __func__ ((const char*) "")
# endif
#endif
void my_default_report_handler( const char* msg,
const char* file,
int line,
const char* func )
{
/* In my case, if I don't have support for __func__, I define
it above to a string of "". */
if ( *func != '\0' )
{
(void)fprintf( stderr, "%s, file %s, line %d, function %s\n",
msg, file, line, func );
}
else
{
(void)fprintf( stderr, "%s, file %s, line %d\n",
msg, file, line );
}
}
#define c_return_value_if_fail( expr, msg, val ) \
do \
{ \
if ( expr ) {} \
else \
{ \
my_default_report_handler( msg, __FILE__, \
__LINE__, __func__ ); \
return (val); \
} \
} while (0)
\endcode
With that machinery in place, you can do the following if you wish.
\code
int main( void )
{
control_struct* cs;
cs = c_new( control_struct, 1 );
c_return_value_if_fail( cs != NULL,
"Structure: Not allocated enough memory",
EXIT_FAILURE );
free( cs );
return 0;
}
\endcode
The 'my_default_report_handler' function can be customized however you
wish. You can add a parameter for '#expr', log messages to a file
instead of stderr, inject a timestamp, make it a no-op if 'msg ==
NULL', popup an error dialog in Windows, ... whatever you want.
You can have also have a c_return_if_fail( expr, msg ) that just
returns instead of returning a value for functions that have 'void' as
the return type. The 'c_return_value_if_fail' macro was inspired from
GLib. Just some ideas to percolate on.
Best regards,
John D.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web