reading a structure containing pointers 
Author Message
 reading a structure containing pointers

Hello

I have never done or thought about this...

Say I ahve this structure:

struct moon {
        int moon_id;
        char name[100];
        float distance;
        float rotate;

Quote:
};

Clearly, I can do a read:

    struct moon *m;
    m =  (struct moon*) malloc(10 * sizeof(struct moon));
    i = write(fd, m, 10 * sizeof(stuct moon));

But suppose I had this:

struct moon {
        int moon_id;
        char  *name
        float distance;
        float rotate;

Quote:
}

and somewhere, I ensured that m->name was pointing at a space
of , say, 100 bytes.

Is there a way to do the same type of  write, or read?



Sun, 20 Apr 2003 04:26:51 GMT  
 reading a structure containing pointers


Quote:
>and somewhere, I ensured that m->name was pointing at a space
>of , say, 100 bytes.

>Is there a way to do the same type of  write, or read?

Yes, I think we covered this last week here. Re-write so the variable thingys
are at the end of the struct like this:

typedef struct {
        int moon_id;
        float distance;
        float rotate;
        char name[1]; /* Yes, one */

Quote:
} Moon;

int thisNameLen = strlen("Io");

/* Do *NOT* cast the return value of malloc(), read the C-FAQ for why.
** Note that strlen only counts two here but since name[1] is already
** one long in the Moon object we don't need to add one for the nul char.
*/
Moon *pMoon = malloc(sizeof *pMoon + thisNameLen);

if (*pMoon)
{
    /* You might consider fwrite, write is not ISO C */
    i = write(fd, pMoon, sizeof *pMoon);
    free(pMoon);

Quote:
}

Note exactly what you want since you need to do this for each Moon you want
but you get the idea. I'm sure you can extend this out.


Sun, 20 Apr 2003 04:39:21 GMT  
 reading a structure containing pointers

Quote:

> Say I ahve this structure:
> struct moon {
>         int moon_id;
>         char name[100];
>         float distance;
>         float rotate;
> };
> Clearly, I can do a read:
>     struct moon *m;
>     m =  (struct moon*) malloc(10 * sizeof(struct moon));
>     i = write(fd, m, 10 * sizeof(stuct moon));

Try not to refer to the type of the variable, for several reasons.
You could do:

      m = malloc (10 * sizeof *m);
      i = write (fd, m, 10 * sizeof *m));

OTOH, write is a POSIX function.  For questions related to POSIX
functions, please post on comp.unix.programmer.  This newsgroup is
about the ISO/ANSI standards for C.

Note that the ISO functions to do the same task here are fwrite and
fread, and not all implementations will have write/read.

Quote:
> But suppose I had this:
> struct moon {
>         int moon_id;
>         char  *name
>         float distance;
>         float rotate;
> }
> and somewhere, I ensured that m->name was pointing at a space
> of , say, 100 bytes.
> Is there a way to do the same type of  write, or read?

Yes, but it's not meaningful.  You'll want to write out the struct
first, then the data at *name.  Note that the pointer you've written
to disk will be meaningless in the loading function.

When reading it, read the struct first, allocate space at name, and
then read the pointer into the space you allocated.  The key here is
to discard the value you've written for name.

--



Sun, 20 Apr 2003 04:47:17 GMT  
 reading a structure containing pointers

Quote:

> Hello

> I have never done or thought about this...

> Say I ahve this structure:

> struct moon {
>         int moon_id;
>         char name[100];
>         float distance;
>         float rotate;
> };

> Clearly, I can do a read:

>     struct moon *m;
>     m =  (struct moon*) malloc(10 * sizeof(struct moon));
>     i = write(fd, m, 10 * sizeof(stuct moon));

> But suppose I had this:

> struct moon {
>         int moon_id;
>         char  *name
>         float distance;
>         float rotate;
> }

> and somewhere, I ensured that m->name was pointing at a space
> of , say, 100 bytes.

> Is there a way to do the same type of  write, or read?

Not with a simple fwrite(), and the file will not be portable.
If you just want to write and read it on the same system you could do
something like:

fwrite(fd, m, sizeof(struct moon));
int i=strlen(name);
fwrite(fd, i, sizeof(int));
fwrite(fd, name, i);

and on read:
read the struct
read the strlen
allocate space for the string
read the string

Altogether a really hard way, and not portable at all.
Easier, more (but not fully) portable and with the advantage that your
file will be readable by human eyes will be to
write the members of the struct to a text file using fprintf and read
them back using fscanf.

Regards
Robert



Sun, 20 Apr 2003 03:45:21 GMT  
 reading a structure containing pointers

Quote:

> Hello

> I have never done or thought about this...

> Say I ahve this structure:

> struct moon {
>         int moon_id;
>         char name[100];
>         float distance;
>         float rotate;
> };

> Clearly, I can do a read:

>     struct moon *m;
>     m =  (struct moon*) malloc(10 * sizeof(struct moon));
>     i = write(fd, m, 10 * sizeof(stuct moon));

> But suppose I had this:

> struct moon {
>         int moon_id;
>         char  *name
>         float distance;
>         float rotate;
> }

> and somewhere, I ensured that m->name was pointing at a space
> of , say, 100 bytes.

> Is there a way to do the same type of  write, or read?

byte reading/writing structs like that isnt very portable in any case.
in the second case, it would write the contents of the pointer variable,
which usually would be some sort of address and would not be valid after
the prog that writes it exits. you should make an algorithm to store
each struct/field in ASCII form, then make another to re-read it back up
into the struct.

- BIG FAT LOAFER



Sun, 20 Apr 2003 06:00:05 GMT  
 reading a structure containing pointers

Quote:
> /* Do *NOT* cast the return value of malloc(), read the C-FAQ for why.
> ** Note that strlen only counts two here but since name[1] is already
> ** one long in the Moon object we don't need to add one for the nul char.
> */

If I remember ok (couldn't find the entry in the C-FAQ you were
referring too) the pro and con of casting were:
Pro casting: will compile with a K&R or C++ compiler
Con casting: you don't get a compiler warning/error if you
     forget to include stdlib.h

Forget to include stblib.h and compiler will assume malloc()
returns an integer.  This could fail on systems were int is different
from void*.

Is this right or am I missing something obvious?

By the way there are many docs on the Internet which
advocate casting:
------------
From the GNU docs for malloc():

The contents of the block are undefined; you must initialize it yourself
(or use calloc instead; see section Allocating Cleared Space). Normally
you would cast the value as a pointer to the kind of object that you want to
store in the block. Here we show an example of doing so, and of initializing
the space with zeros using the library function memset (see section Copying
and Concatenation):
struct foo *ptr;
...
ptr = (struct foo *) malloc (sizeof (struct foo));
if (ptr == 0) abort ();
memset (ptr, 0, sizeof (struct foo));

You can store the result of malloc into any pointer variable without a cast,
because ISO C automatically converts the type void * to another type of
pointer when necessary. But the cast is necessary in contexts other than
assignment operators or if you might want your code to run in traditional C.
-------
From the SYSTEM V unix man page:

Note: Always cast the value returned by malloc(), realloc(), calloc(),
memalign(), valloc() or alloca().
-------

Verify for yourself at:
http://www.gnu.org/manual/glibc-2.0.6/html_chapter/libc_3.html
http://www.cs.princeton.edu/courses/archive/spring00/cs217/assignment...
loc.3.html



Sun, 20 Apr 2003 15:49:40 GMT  
 reading a structure containing pointers

Quote:

> If I remember ok (couldn't find the entry in the C-FAQ you were
> referring too)

http://www.eskimo.com/~scs/C-faq/q7.7.html  

Quote:
> the pro and con of casting were:
> Pro casting: will compile with a K&R or C++ compiler

Why would I want my code to compile in a compiler written for
another language?  I could even further restrict the usefulness
of my code by figuring out ways it could pass as Perl or Java,
I suppose.  Does that sound like a good idea to you too?

For that matter, K&R C can be considered a separate language from
C90, just as C90 can be considered separate from C99.  The difference
is, C99 is coming, but K&R C is gone.  Therefore it's implied that one
should try to keep code valid for C99, but not at all so for K&R C.

Quote:
> Con casting: you don't get a compiler warning/error if you
>      forget to include stdlib.h

What if the sizeof void * != sizeof int?  What if the two are stored
differently for some reason?  The warning might not just be superficial.

Once, long ago, I forgot to include <math.h> and my compiler didn't
warn me about a lack of prototypes.  Just calling pow crashed.  I
assume somewhere, something similar could happen with malloc.

Quote:
> From the GNU docs for malloc():
> ptr = (struct foo *) malloc (sizeof (struct foo));
> if (ptr == 0) abort ();
> memset (ptr, 0, sizeof (struct foo));

This is all nice, except I'd do at least five things differently
for readability and portability reasons.  Maybe something like
this:

  ptr = malloc (sizeof *ptr);
  if (ptr == NULL) exit(EXIT_FAILURE);
  memset (ptr, 0, sizeof *ptr);

Besides, since when is GNU authoritative?  *ducks*

Quote:
> Note: Always cast the value returned by malloc(), realloc(), calloc(),
> memalign(), valloc() or alloca().

It also says to include <malloc.h>.  What do you think you should
infer from this fact?

Anyway, please do a search on dejanews for this subject, so you can
see what arguments have already been had on it.  I'm sure many people
have done a better job of refuting your point already.

--



Sun, 20 Apr 2003 07:47:26 GMT  
 reading a structure containing pointers

Quote:
>If I remember ok (couldn't find the entry in the C-FAQ you were
>referring too) the pro and con of casting were:
>Pro casting: will compile with a K&R or C++ compiler
>Con casting: you don't get a compiler warning/error if you
>     forget to include stdlib.h

>Forget to include stblib.h and compiler will assume malloc()
>returns an integer.  This could fail on systems were int is different
>from void*.

This is correct.

Quote:
>Is this right or am I missing something obvious?

>By the way there are many docs on the Internet which
>advocate casting:
>------------
>From the GNU docs for malloc():

Give me a reason for casting a void *? C will auto-cast (my words) the
returned pointer to match the pointer it's being assigned to. You can put
parenthesis around everything to, doesn't mean you should.

Quote:
>You can store the result of malloc into any pointer variable without a cast,
>because ISO C automatically converts the type void * to another type of
>pointer when necessary. But the cast is necessary in contexts other than
>assignment operators or if you might want your code to run in traditional C.

Traditional C? I only worry about ANSI/ISO C and the extensions my modern
compiler apply to the platform I'm working on. I have a luxury it would seem.

Quote:
>-------
>From the SYSTEM V unix man page:

>Note: Always cast the value returned by malloc(), realloc(), calloc(),
>memalign(), valloc() or alloca().

At one point I think they recommended cutting holes in your scull if you had
headaches. They dropped that practice just after the cast on malloc's return
value.


Sun, 20 Apr 2003 09:11:55 GMT  
 reading a structure containing pointers

Quote:

> > /* Do *NOT* cast the return value of malloc(), read the C-FAQ for why.
> > ** Note that strlen only counts two here but since name[1] is already
> > ** one long in the Moon object we don't need to add one for the nul char.
> > */

> If I remember ok (couldn't find the entry in the C-FAQ you were
> referring too) the pro and con of casting were:
> Pro casting: will compile with a K&R or C++ compiler

No, it won't, unless there are no more interesting lines in the code
than your malloc() call. There are many more things in ISO C that won't
compile in C++; a variable called new is just one trivial example. Ditto
for K&R; for example, would you remove all prototypes from your code
just to keep it compiling under K&R? You'll have to, you know.

Quote:
> Con casting: you don't get a compiler warning/error if you
>      forget to include stdlib.h

And: is likely to break if you ever change the type of the pointer.

And, perhaps most importantly: it gives the wrong semantic message.
Sure, it may work, but you give the impression that you think the cast
is necessary, or that something weird is going on. Never cast things you
don't have to cast; a cast should be a red flashing light telling you
that something is out of the ordinary here, not something you use
because it happens to make your broken code compile. A wrong cast can be
a time-bomb in your code. Don't, ever, cast unless you know that you
_must_, and you also know _why_.

Quote:
> Forget to include stblib.h and compiler will assume malloc()
> returns an integer.  This could fail on systems were int is different
> from void*.

It could fail under a lot of circumstances, including ints being as
large as void *s, but being returned in different registers.

Quote:
> Is this right or am I missing something obvious?

> By the way there are many docs on the Internet which
> advocate casting:
> ------------
> From the GNU docs for malloc():

Don't, ever, take anything GNU claims as authoritative or even likely to
be true under ISO C. Their attitude towards compliance is as arrogant as
it is deplorable.

Quote:
> From the SYSTEM V unix man page:

That's not only ancient, it's system-specific and meant to be.

Richard



Sun, 20 Apr 2003 18:37:30 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Pointers to Structure that contains pointer to Function

2. dereferencing pointer to a structure containing a pointer to int

3. structure containing pointer to char over the network

4. How Do I fwrite() and fread() A Structure that contains pointers to dynamic data

5. self contained pointers to structures

6. Structure containing pointer problem

7. memory block containing pointers, aka pointer to pointer i believe

8. Marshaling a structure containing a aray of different structures

9. how to dynamically allocate a structure containing pointer type structures?

10. printing a string contained in a structure

11. Sorting a last names that are contained within a structure

12. A question about a structure containing ':'

 

 
Powered by phpBB® Forum Software