[comp.lang.c] Initializing a pointer inside a struct

f90angu@fy.chalmers.se (Andreas Gunnarsson) (04/17/91)

I've tried this:

struct
{
   ...
   int *int_list;
   ...
} list_of_structs[] =
{
   { ..., {1, 2, 3, -1}, ...},
   { ..., {4, -1}, ...},
   .
   .
   .
};

It doesn't work. I know I could declare the lists of integers as separate
variables and use the address, but it would be much harder to see what data
belongs where, and I would have to use *lots* of variable names.
I could also write 'int int_list[MAX];' instead of 'int *int_list;', but in
that case lots of space would be wasted if there is big variance in length.

Is there any simple way to do it?


-- 
==============================================================================
73 es 88 de SM7TLS          f90angu@fy.chalmers.se          Andreas Gunnarsson
==============================================================================

torek@elf.ee.lbl.gov (Chris Torek) (04/17/91)

In article <1991Apr17.105139.16331@fy.chalmers.se> f90angu@fy.chalmers.se
(Andreas Gunnarsson) writes:
>I've tried this:
>
>struct {
>   ...
>   int *int_list;
>   ...
>} list_of_structs[] =
>{
>   { ..., {1, 2, 3, -1}, ...},
>   { ..., {4, -1}, ...},
>   ...
>};
>
>It doesn't work. I know I could declare the lists of integers as separate
>variables and use the address, but it would be much harder to see what data
>belongs where, and I would have to use *lots* of variable names.

This is pretty much the only way to do it.

>I could also write 'int int_list[MAX];' instead of 'int *int_list;', but in
>that case lots of space would be wasted if there is big variance in length.

Right.

>Is there any simple way to do it?

Use a preprocessor (not `cpp'); have it emit something like

	int L0[] = { 1, 2, 3, -1 };
	int L1[] = { 4, -1 };
	...
	struct ... list_of_structs[] = {
		{ ..., L0, ... },
		{ ..., L1, ... },
		...
	};

where each Li is the array to which list_of_structs[i] should point.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

pds@lemming.webo.dg.com (Paul D. Smith) (04/18/91)

[] On 17 Apr 91 10:51:39 GMT, f90angu@fy.chalmers.se (Andreas Gunnarsson) said:

AG> I've tried this:

AG> struct
AG> {
AG>    ...
AG>    int *int_list;
AG>    ...
AG> } list_of_structs[] =
AG> {
AG>    { ..., {1, 2, 3, -1}, ...},
AG>    { ..., {4, -1}, ...},
AG>    .
AG>    .
AG>    .
AG> };

AG> It doesn't work. I know I could declare the lists of integers as
AG> separate variables and use the address, but it would be much
AG> harder to see what data belongs where, and I would have to use
AG> *lots* of variable names.  I could also write 'int int_list[MAX];'
AG> instead of 'int *int_list;', but in that case lots of space would
AG> be wasted if there is big variance in length.

You can't do it, because the types are different.  The only exception
is a special case for strings, and you use "abcd" syntax instead of
{'a', 'b', 'c', 'd'}, so it's easy to see the special case.

Remember that a {1, 2, 3, 4} is an array of ints, with memory
allocated (i.e., array[4]).  int *array is a pointer to an int, with
no memory allocated.  C does not allow you to have the compiler
"infer" memory allocation for anything except strings, as above.

I would go with the same structure you have above (i.e., don't use
arrays), and declare the integers as seperate variables, as you
mentioned.  True, it's harder to see the relationship.  You can get
around the "lots of variable names" problem by making them all static
(yes, there are still lots but at least they don't exist beyond the
scope of the file).

I've written a couple of compilers as software development tools which
generate static initializations for complex structures, and have run
into this problem as well.  The best you can do is declare them
seperately.

                                                                paul
-----
 ------------------------------------------------------------------
| Paul D. Smith                          | pds@lemming.webo.dg.com |
| Data General Corp.                     |                         |
| Network Services Development Division  |   "Pretty Damn S..."    |
| Open Network Systems Development       |                         |
 ------------------------------------------------------------------

stachour@sctc.com (Paul Stachour) (04/24/91)

re: the problem
>[] On 17 Apr 91 10:51:39 GMT, f90angu@fy.chalmers.se (Andreas Gunnarsson) said:

>AG> I've tried this:

>AG> struct
>AG> {
>AG>    ...
>AG>    int *int_list;
>AG>    ...
>AG> } list_of_structs[] =
>AG> {
>AG>    { ..., {1, 2, 3, -1}, ...},
>AG>    { ..., {4, -1}, ...},
>AG>    .
>AG>    .
>AG>    .
>AG> };

=====
The solution suggested was that one uses a set of statics,
and then gives the pointer to those items.
-----
Those trying the solution should be aware that many C compilers
for embedded systems (e.g, multi-tasking C programs) cannot
get the correct addresses into the initialized structures due
to the way in which the compiler and run-time startup is built.
I seldom have these problems on virtural-memory systems like Unix
or on one-process physical memory systems like MS-DOS, but nearly
every compiler I have ever used for C on top of physical-memory
multi-porcess structures gets at least one of its addressing
modes between "varieties of data" (such as static-static,
static-const, static-exec, ...) wrong.

...Paul

-- 
Paul Stachour          SCTC, 1210 W. County Rd E, Suite 100           
stachour@sctc.com          Arden Hills, MN  55112
                             [1]-(612) 482-7467

steve@taumet.com (Stephen Clamage) (04/24/91)

pds@lemming.webo.dg.com (Paul D. Smith) writes:

>Remember that a {1, 2, 3, 4} is an array of ints, with memory
>allocated (i.e., array[4]).  int *array is a pointer to an int, with
>no memory allocated.  C does not allow you to have the compiler
>"infer" memory allocation for anything except strings, as above.

These comments are simply incorrect.  The notation {1, 2, 3, 4} is
used to initialize a declared aggregate.  It is not, and does not
represent, an array, although it can be used to initialize one.
For example:
	int i1[4] = {1, 2, 3, 4};
	long l2[] = {1, 2, 3, 4};
	struct s { int a, b, c, d; } s1 = {1, 2, 3, 4};
	struct t { float x[2]; short y; char z; } = {1, 2, 3, 4};

C does allow the compiler to "infer memory allocation", as in the second
example line.  The size of array l2 is determined by the compiler based
on the number of initializers supplied, and the compiler allocates that
much space for it.  This array is not a "string", which usually means
"array of char".  (The last example is legal, but not recommended style,
as the initialization is not "fully bracketed".  It is better style to
write it as {{1, 2}, 3, 4}, or better still, {{1.0f, 2.0f}, 3, 4}, but
the example as shown is legal.)
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com