need some expert to 'vette' my code 
Author Message
 need some expert to 'vette' my code

I'm new to programming C in linux environment & need some expert advice
on whether I've handled pointers for record structures from a file
correctly.  my prog juz wanna read out structures stored in a file, and
I need to use the low level read/write functions.

I have a record counter in the main menu which i pass in here as a
pointer since I'll be doing the counting here.  this will result in
segmentation fault, though.  the last time I ran a trace it broke at the
line
(if *reccount == 0)
        head = new;

i dunno why this is so.  can anybody tell?

/*
 * readfile - reads file descriptor specified by caller
 * param
 *      int fd - file descriptor
 *      int *reccount - pointer to main menu's record counter
 * return struct shares * - pointer to the head of list
 */
struct shares *readfile(int fd, int *reccount)
{
   ssize_t readsize;    /* mem size read from file */
   struct shares *head = NULL, *current;
   struct shares *new = (struct shares *)malloc(sizeof(struct shares));

   /* set counter to 0 since only reads at startup */
   *reccount = 0;

   /* while some data being read */
   while ((readsize = read(fd, new, sizeof(struct shares))) > 0)
   {
      if (readsize != sizeof(struct shares))
         printf("read size different : %d/%d bytes \n", readsize,
sizeof(struct shares));

      /* initialise the fresh record's next pointer to NULL */
      new->next = NULL;

      if (*reccount == 0)
         head = new;
      else
         current->next = new;

      current = new;
      *reccount ++;
      new = (struct shares *)malloc(sizeof(struct shares));
   }

   /* if !EOF then error */
   if (readsize < 0)
      printf("errno = %d\n", errno);

   /* report */
   printf("read size : %d/%d bytes\n", readsize, sizeof(struct shares));
   printf("%d records read.\n", *reccount);

   return head; /* address of 1st record struct */

Quote:
}

thanx!
Aaron
--



Wed, 06 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code

Quote:

>       *reccount ++;

Change that to: (*reccount)++;
But I don't know if this was what caused the segfault, since I
didn't get one.

The function also leaks the last structure it allocates.
--



Thu, 07 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code
IceLava a crit dans le message ...

Quote:
>I'm new to programming C in linux environment & need some expert advice
>on whether I've handled pointers for record structures from a file
>correctly.  my prog juz wanna read out structures stored in a file, and
>I need to use the low level read/write functions.

>I have a record counter in the main menu which i pass in here as a
>pointer since I'll be doing the counting here.  this will result in
>segmentation fault, though.  the last time I ran a trace it broke at the
>line
>(if *reccount == 0)
> head = new;

>i dunno why this is so.  can anybody tell?

Well, your code uses non standard functions and definitions(struct shares,
ssize_t etc...), it is not easy to test your code on a standard compiler !

I suppose that you call the function like this :

int iReccount;

    p= readfile(fd, &iReccount);

May be you have made a cuttent error that is to use a non initialised
pointer like this :

int *piReccount;

    p= readfile(fd, piReccount);

This could explain the execution error.

Some remarks concerning your coding :

Quote:
>   struct shares *new = (struct shares *)malloc(sizeof(struct shares));

- "new" is a reserved key word in C++. You'd better avoid to use it !
-  It is a good idea to use calloc() instead of malloc(). The data will be
initialized to 0.

  struct shares *pNew = (struct shares *)calloc(sizeof(struct shares),1);

Quote:
>   /* set counter to 0 since only reads at startup */
>   *reccount = 0;

to avoid bad surprises, it is better to check the pointer before use :

   assert(reccount!=NULL);

see your documentation about assert() : Highly recommended to write reliable
code !

Quote:
>   /* while some data being read */
>   while ((readsize = read(fd, new, sizeof(struct shares))) > 0)
>   {
>      if (readsize != sizeof(struct shares))
>         printf("read size different : %d/%d bytes \n", readsize,
>sizeof(struct shares));

This generally means that you are reading the end of the file. It is not an
error.

Quote:
>      /* initialise the fresh record's next pointer to NULL */
>      new->next = NULL;

So "new" is a chain list ! first new !

Quote:
>      if (*reccount == 0)

If "reccount" points to a valid memory zone, no prolem !

Quote:
>      *reccount ++;

I prefer
      (*reccount)++;

--
HS

--



Thu, 07 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code

Quote:

>Well, your code uses non standard functions and definitions(struct shares,
>ssize_t etc...), it is not easy to test your code on a standard compiler !

Indeed.

Quote:
>>   struct shares *new = (struct shares *)malloc(sizeof(struct shares));

>- "new" is a reserved key word in C++. You'd better avoid to use it !

Eh?  He is writing C, not C++; why should he care what is reserved
in C++?  "var" is a keyword in Pascal, so perhaps we should avoid that
too? :-)

Quote:
>-  It is a good idea to use calloc() instead of malloc(). The data will be
>initialized to 0.

Calloc() produces all-bits-zero, which is not always appropriate.
I almost never use calloc() myself.  If you have some data structure
that needs to be set to mostly-zero or all-zero, and it might
contain objects of floating-point or pointer type, you can do
something like this instead:

        static struct S zero_S;
        struct S *p = malloc(sizeof *p); /* no cast here; C is not C++ */
        ... make sure p != NULL ...
        *p = zero_S;

Since zero_S is static, all its members are implicitly set to an
appropriate kind of zero, whatever bit pattern that may be, so this
sets *p to all-zero-values, which may or may not be all-zero-bits.
--
In-Real-Life: Chris Torek, Berkeley Software Design Inc


--



Fri, 08 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code

Quote:




[Snip]

Quote:

> >>   struct shares *new = (struct shares *)malloc(sizeof(struct shares));

> >- "new" is a reserved key word in C++. You'd better avoid to use it !

> Eh?  He is writing C, not C++; why should he care what is reserved
> in C++?  "var" is a keyword in Pascal, so perhaps we should avoid that
> too? :-)

A significant number of compilers, used to compile C code, are really
C++ compilers.  Some of those will {*filter*}on this sort of code, while
others will have compiler options to turn off C++ compilation.

Also keep in mind that one option for reusing C code is within a C++
program.  In some instances, that means recompiling it as C++.

Quote:

> >-  It is a good idea to use calloc() instead of malloc(). The data will be
> >initialized to 0.

> Calloc() produces all-bits-zero, which is not always appropriate.
> I almost never use calloc() myself.  [Snip ...]

Same here.  Your milage will vary, obviously, but I've found that use of
calloc is often slower than use of malloc (presumably because of the
initialisation).  Generally, I prefer to use malloc and then initialise
explicitly.  Since I rarely have to initialise a complete new data
structure
to zero (there is usually one or more fields that will be initialised to
non-zero), I normally only use malloc.

In short, use of calloc or malloc is a trade-off.  In my code, the
trade-offs
favour malloc.

-<Automagically included trailer>
Robert O'Dowd                       Ph    +61 (8) 8259 6546
MOD/DSTO                            Fax    +61 (8) 8259 5139
P.O. Box 1500                       Email:

Salisbury, South Australia, 5108

Disclaimer: Opinions above are mine and may be worth what you paid for
them
--



Fri, 08 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code


Quote:
>Calloc() produces all-bits-zero, which is not always appropriate.
>I almost never use calloc() myself.

(A side note:  I suspect Chris Torek has not written any code in the last
five years which will ever be executed on a machine on which all-bits-zero
doesn't work for pointers and floating point types.  This turns out to be
a part of the reason people in alt.folklore.computers cited "the ability to
find old posts by Chris Torek" to be a major advantage of a long-term Usenet
archive.)

Quote:
>If you have some data structure
>that needs to be set to mostly-zero or all-zero, and it might
>contain objects of floating-point or pointer type, you can do
>something like this instead:
>    static struct S zero_S;
>    struct S *p = malloc(sizeof *p); /* no cast here; C is not C++ */
>    ... make sure p != NULL ...
>    *p = zero_S;
>Since zero_S is static, all its members are implicitly set to an
>appropriate kind of zero, whatever bit pattern that may be, so this
>sets *p to all-zero-values, which may or may not be all-zero-bits.

I'm sure some of the newbies want to know *why* this works and the other
doesn't.

Here's the idea.  There Exist (that's C guru for "I've never seen or touched,
but I have been told about theoretical designs for") machines on which the
floating point value 0.0, or the null pointer, is not actually stored with
all the bits in memory zeroed.  There are many and varied reasons for this;
in practice, You Don't Need To Know.

The problem is this:

If you say
        static int p, *q;
the compiler, at compile-time, gets to look at this and say "p is an int,
I'll write a 0 there.  oooh, q is a pointer, better put the special magic null
value there".

If you say
        void *v = calloc(sizeof(struct foo), 10);
there's no way for 'calloc' to know what it needs to do.  You can create a
situation where even with all the information the compiler starts with, you
can trick the system into creating a block of memory with "the wrong type of
zero".

So, it doesn't try.  It just writes all-bits-zero and hopes.

This means you lose, if you're on a weird system.  So, we end up with stuff
like what Chris shows above.

In C9X, you can get one step simpler:
        *p = (struct S) { 0 };

This magically does the right thing, without the explicit creation of a static
object.  (In fact, the chances are that, on a reasonable compiler, this will
end up creating just about exactly the same code that the other one did.)

-s
--

C/Unix wizard, Pro-commerce radical, Spam fighter.  Boycott Spamazon!
Will work for interesting hardware.  http://www.plethora.net/~seebs/
Visit my new ISP <URL:http://www.plethora.net/> --- More Net, Less Spam!
--



Fri, 08 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code

Quote:


> > Eh?  He is writing C, not C++; why should he care what is reserved
> > in C++?  "var" is a keyword in Pascal, so perhaps we should avoid that
> > too? :-)

> A significant number of compilers, used to compile C code, are really
> C++ compilers.  Some of those will {*filter*}on this sort of code, while
> others will have compiler options to turn off C++ compilation.

tsk. A compiler that compiles both C and C++ (and other language) code
should be able to tell what language you're using (on some platforms)
from the source code file extension, and set itself accordingly.

<disclaimer>
(Note : _On_some_platforms_. I know that the standard has nothing to say
about the form that source code is supplied in, even to the extent of
not neccessarily specifying that a file system need exist.)
</disclaimer>

Quote:
> Also keep in mind that one option for reusing C code is within a C++
> program.  In some instances, that means recompiling it as C++.

Agreed. I'm not saying that avoiding C++ identifiers is not a good idea.
It is. It should just not be _neccessary_.

Adam

--
Apparently [...] police in many lands are now complaining that local
arrestees are insisting on having their Miranda rights read to them,
just like perps in American TV cop shows. When it's explained to them
that they are in a different country, where those rights do not exist,
they become outraged. Starsky and Hutch reruns, dubbed into diverse
languages, may turn out, in the long run, to be a greater force for
human rights than the [United States] Declaration of Independence.
-- Neal Stephenson (Cryptonomicon -
http://www.*-*-*.com/ ~mccoy/beginning_print.html)

----------------
The opinions expressed in this email are mine alone, and do not
neccesarily represent those of my employer, my parents, or the people
who wrote the email software I use.
--



Fri, 08 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code


Quote:
>Eh?  He is writing C, not C++; why should he care what is reserved
>in C++?  "var" is a keyword in Pascal, so perhaps we should avoid that
>too? :-)

Well there is a serious difference, C code can generally be compiled by
a C++ compiler (and often is).  It would be a rare piece of C source
that compiled with a Pascal compiler.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
--



Fri, 08 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code

says...

[ ... ]

Quote:
> Here's the idea.  There Exist (that's C guru for "I've never seen or touched,
> but I have been told about theoretical designs for") machines on which the
> floating point value 0.0, or the null pointer, is not actually stored with
> all the bits in memory zeroed.  There are many and varied reasons for this;
> in practice, You Don't Need To Know.

If memory about what machines you've used serves me correctly, you
HAVE seen, touched and in fact regularly use machines that don't
necessarily use all-bits-zero to represent 0.0.  In fact, machines
that require all bits to be zero to represent 0.0 are probably in the
minority at the present time -- the typical Intel, PowerPC, SPARC,
etc., do NOT require this.  In fairness, I should point out that I
believe on all of them, all bits being set to 0 will give a value of
0.0 when treated as floating point, but most will treat a number of
other bit-patterns as values of 0.0 as well.

If memory serves, the ancient CDC mainframes were what I'd consider a
bit smarter about things: they treated a pattern all 0 bits as roughly
equivalent to what IEEE floating point would call a signalling NaN.  
This meant that most of the time if you tried to use an un-initialized
floating point variable, the program would immediately tell you so.  
OTOH, it's barely possible that the pattern was not all zeroes, but
the compiler initialized unused memory to the right pattern; it's been
long enough that I don't remember for sure.
--



Fri, 08 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code

Quote:


>says...
>> Here's the idea.  There Exist (that's C guru for "I've never seen or touched,
>> but I have been told about theoretical designs for") machines on which the
>> floating point value 0.0, or the null pointer, is not actually stored with
>> all the bits in memory zeroed.  There are many and varied reasons for this;
>> in practice, You Don't Need To Know.
>In fairness, I should point out that I
>believe on all of them, all bits being set to 0 will give a value of
>0.0 when treated as floating point, but most will treat a number of
>other bit-patterns as values of 0.0 as well.

Yeah.  I've never actually seen all-bits-zero not work.  Of course, it's
probably been five or ten years since I experimented at all; I don't really
care.

See, I have source, and I've read how calloc really works.
        ...
        type_t t = precognitive_rtti(v);
        if (!strncmp(t, "pointer to", 10) || strstr(t, "float")) {
                FILE *fp = fopen("/dev/boss", "w+");
                fprintf(fp, "it is imperative that all of our software be tested on a CDC mainframe.\n");
                fclose(fp);
        }

They just wait for you to get careless, then pounce.

-s
--

C/Unix wizard, Pro-commerce radical, Spam fighter.  Boycott Spamazon!
Will work for interesting hardware.  http://www.plethora.net/~seebs/
Visit my new ISP <URL:http://www.plethora.net/> --- More Net, Less Spam!
--



Fri, 08 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code

says...

Quote:


> >A good point.  If I had a ba{*filter*}t (a LARGE ba{*filter*}t) I'd keep one
> >down there to test things on.  Unfortunately, the supply of vestal
> >{*filter*}s isn't what it once was, so I'm afraid keeping one running
> >would be awfully hard nowadays anyway...and rebooting takes a trained
> >team around a half hour at best!

> I'd settle for a sufficiently good "arbitrary implementation simulator".

I know the idea's come up before, but I have to admit it'd be kind of
fun, wouldn't it?

Quote:
> >Ah, so there's finally somebody else who realizes what computers
> >really are: malevolent creatures from another dimension, sent here to
> >punish us for our good deeds.  (It must be punishment for good deeds--
> >I'm the nicest person I've ever met, and they cause me problems ALL

> Maybe you should run Unix.  <grin, duck, and run>

Oh, but I do run UNIX, which is the major problem.  NT is a decided
contrast since it mostly runs itself.  Unfortunately, there's another
contrast: NT doesn't run well on a SPARC.  This is a decided contrast
to Solaris, which doesn't run well on...anything.
--



Sat, 09 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code

Quote:



>>A good point.  If I had a ba{*filter*}t (a LARGE ba{*filter*}t) I'd keep one
>>down there to test things on.  Unfortunately, the supply of vestal
>>{*filter*}s isn't what it once was, so I'm afraid keeping one running
>>would be awfully hard nowadays anyway...and rebooting takes a trained
>>team around a half hour at best!

>I'd settle for a sufficiently good "arbitrary implementation simulator".

     Bring on the nasal demons!

[snip]

Sincerely,

Gene Wirchenko

Computerese Irregular Verb Conjugation:
     I have preferences.
     You have biases.
     He/She has prejudices.
--



Sun, 10 Feb 2002 03:00:00 GMT  
 need some expert to 'vette' my code

Quote:

> Here's the idea.  There Exist (that's C guru for "I've never seen or touched,
> but I have been told about theoretical designs for") machines on which the
> floating point value 0.0, or the null pointer, is not actually stored with
> all the bits in memory zeroed.  There are many and varied reasons for this;
> in practice, You Don't Need To Know.

In fact, There Is (that's my guess as to what a C guru might use for
"I've seen and/or touched a real machine on which...") an old machine
still in occasional use, the Commodore 64, whose built-in ROM BASIC
interpreter manipulated five-byte (40-bit) floating point values (one
exponent byte, four manitissa bytes). For reasons You Don't Need To
Know, if the exponent byte was zero, the floating point value as a whole
was considered to be zero, regardless of any values in any of the
mantissa bytes.

And this relates to C because the ROM floating point routines were
sufficiently orthogonal (to use a word that's been floating about here
lately) to the remainder of the BASIC interpreter that they could be
called by other, completely independent programs running on the C64.
Which is how at least one C compiler for the C64 handled the problem of
providing floating point support.

- Anton
--



Sun, 10 Feb 2002 03:00:00 GMT  
 
 [ 13 post ] 

 Relevant Pages 

1. need expert 'c' programmer

2. Need source code of CD's manager program

3. Need C routine to get PQ code on CD's

4. Pascal's Triangle:Need help Coding!

5. Pascal's Triangle:Need help Coding!

6. Pascal's Triangle: Need help Coding!

7. Need code for NT Process ID's and respective threads

8. Need help with DirectX Media's DVD code

9. Question from Linden's Expert C Programming: Declarations

10. What's a C expert?

11. i'm no expert, but i think yes

12. EXPERT'S HELP REQUIRED

 

 
Powered by phpBB® Forum Software