is this valid code? 
Author Message
 is this valid code?

Good morning,
The following piece of code is not intended to do something
meaningful, I just want to know if there is any statement in it
which breaks the rules (and why it does so).
I have put comments before the lines I am especially interested.
I wuold really appreciate your comments and thank you in advance for
spending your time on that
Robert

#include <stdio.h>
#include <malloc.h>
#include <memory.h>

struct s
{
    int a;
    unsigned int b;
    long c;
    unsigned long d;
    float e;
    double f;
    char *g;
    void *h;

Quote:
};

int main(void)
{
    void *pv;
    char *pc;
    struct s *ps;
    unsigned int i;

/*I think the following 7 lines are ok. I am malloc()ing some space
and initializing it to 0, and I am dealing with a pointer to void
throughout*/

    pv=malloc((int)sizeof(struct s));
    if(pv==NULL)
    {
        printf("Malloc failed on pv\n");
        return 1;
    }
    memset(pv,0,(int)sizeof(struct s));

/*casting a void pointer to a char pointer is allowed AFAIK,
assigning values to the array-elements also (please correct me if I
am wrong)*/

    pc=(char *)pv;
    for(i=0; i<(int)sizeof(struct s); i++)
    {
        pc[i]='0';
    }

/*ok, now I am casting the void pointer to a pointer to a struct
containing int, long, floats, doubles and pointers. I think this
should not do any harm as long as I consider the struct still
uninitialized. I do not use any of the members nor do I dereference
one of the pointers. Im I right here?*/

    ps=(struct s *)pv;

/*now I assign (hopefully ;)) correct values to all of the members*/

    ps->a=-1;
    ps->b=1;
    ps->c=-1L;
    ps->d=1L;
    ps->e=(float)1.5;
    ps->f=1.5;
    ps->g=malloc(10);
    if(ps->g==NULL)
    {
        printf("Malloc failed on ps->g\n");
        return 1;
    }
    memset(ps->g,'a',10);
    ps->h=malloc(10);
    if(ps->h==NULL)
    {
        printf("Malloc failed on ps->h\n");
        return 1;
    }
    memset(ps->h,'b',10);
    memcpy(ps->g,(const void *)ps->h,10);
    return 0;

Quote:
} // main

/*so - is there anything which violates the standard?*/
<off topic>
I still don't know if my linelength is ok :( could you pls give me a
feedback on that ?
<end off topic>
Thanks and kind regards
Robert


Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?

Quote:
>The following piece of code is not intended to do something
>meaningful, I just want to know if there is any statement in it
>which breaks the rules (and why it does so).

Plenty of them!

Quote:
>#include <stdio.h>
>#include <malloc.h>
>#include <memory.h>

There is no such thing as <malloc.h> and <memory.h> in C.  You failed
to include <stdlib.h>, needed by malloc() and <string.h> needed by
memset() and memcpy().  Have a careful look at Appendix B of K&R2!

Quote:
>struct s
>{
>    int a;
>    unsigned int b;
>    long c;
>    unsigned long d;
>    float e;
>    double f;
>    char *g;
>    void *h;
>};

>int main(void)
>{
>    void *pv;
>    char *pc;
>    struct s *ps;
>    unsigned int i;

>/*I think the following 7 lines are ok.

You're way too optimistic :-)

Quote:
>    pv=malloc((int)sizeof(struct s));

Not technically wrong, but plain silly.  malloc expects a size_t argument,
sizeof produces a size_t value, but you convert it to int, so that the
compiler will have to convert it back to size_t before passing it to
malloc.  size_t is an unspecified unsigned type.

Quote:
>    if(pv==NULL)
>    {
>        printf("Malloc failed on pv\n");

Error messages are supposed to be sent to stderr, not to stdout.

Quote:
>        return 1;

The proper method of reporting failure is to use EXIT_FAILURE, defined in
<stdlib.h>.  For all you know, 1 might mean successful termination.

Quote:
>    }
>    memset(pv,0,(int)sizeof(struct s));

The same comment as above about the cast to int.  The third argument of
memset has type size_t.

You could have achieved the effect of the memset call by allocating the
memory with calloc instead of malloc.

Quote:
>/*casting a void pointer to a char pointer is allowed AFAIK,
>assigning values to the array-elements also (please correct me if I
>am wrong)*/

>    pc=(char *)pv;

    pc = pv;

is enough.

Quote:
>    for(i=0; i<(int)sizeof(struct s); i++)

What do you need the cast to int for?  Especially since i is defined as
unsigned int!

Quote:
>    {
>        pc[i]='0';
>    }

Technically correct, but useless as an initialisation.  Not a single
field of your struct will be properly initialised by this loop.

Quote:
>/*ok, now I am casting the void pointer to a pointer to a struct
>containing int, long, floats, doubles and pointers. I think this
>should not do any harm as long as I consider the struct still
>uninitialized.

It really doesn't matter if the struct is initialised or not.

Quote:
>I do not use any of the members nor do I dereference
>one of the pointers. Im I right here?*/

Yes.

Quote:
>    ps=(struct s *)pv;

    ps = pv;

is the preferred way of doing it.  Avoid casting pointers in C, unless
strictly necessary.

Quote:
>/*now I assign (hopefully ;)) correct values to all of the members*/

>    ps->a=-1;
>    ps->b=1;
>    ps->c=-1L;
>    ps->d=1L;
>    ps->e=(float)1.5;

The preferred form is:

    ps->e = 1.5f;

- Show quoted text -

Quote:
>    ps->f=1.5;
>    ps->g=malloc(10);
>    if(ps->g==NULL)
>    {
>        printf("Malloc failed on ps->g\n");
>        return 1;
>    }
>    memset(ps->g,'a',10);
>    ps->h=malloc(10);
>    if(ps->h==NULL)
>    {
>        printf("Malloc failed on ps->h\n");
>        return 1;
>    }
>    memset(ps->h,'b',10);
>    memcpy(ps->g,(const void *)ps->h,10);

The cast is unnecessary.

You should really "hide" the constant 10 behind a macro in real code.

Quote:
>    return 0;
>} // main

Unless you have a C99 compiler, the // comments are a syntax error in C.

Quote:
>/*so - is there anything which violates the standard?*/

The only violations are the wrong headers included for malloc, memset and
memcpy and the // comment.

Stylistic comment: don't be afraid of using white space in your
expressions.  There is no harm in having them more readable :-)

Quote:
>I still don't know if my linelength is ok :( could you pls give me a
>feedback on that ?

Looks fine to me.

Here's your full program, rewritten in correct and idiomatic C:

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

#define SIZE 10

struct s
{
    int a;
    unsigned int b;
    long c;
    unsigned long d;
    float e;
    double f;
    char *g;
    void *h;

Quote:
};

int main(void)
{
    void *pv;
    char *pc;
    struct s *ps;
    int i;

    pv = malloc(sizeof(struct s));
    if (pv == NULL)
    {
        fprintf(stderr, "Malloc failed on pv\n");
        return EXIT_FAILURE;
    }
    memset(pv, 0, sizeof(struct s));

    pc = pv;
    for (i = 0; i < sizeof(struct s); i++)
        pc[i] = '0';

    ps = pv;

    ps->a = -1;
    ps->b = 1;
    ps->c = -1L;
    ps->d = 1L;
    ps->e = 1.5f;
    ps->f = 1.5;
    ps->g = malloc(SIZE);
    if(ps->g == NULL)
    {
        fprintf(stderr, "Malloc failed on ps->g\n");
        return EXIT_FAILURE;
    }
    memset(ps->g, 'a', SIZE);
    ps->h = malloc(SIZE);
    if(ps->h == NULL)
    {
        fprintf(stderr, "Malloc failed on ps->h\n");
        return EXIT_FAILURE;
    }
    memset(ps->h, 'b', SIZE);
    memcpy(ps->g, ps->h, SIZE);
    return 0;

Quote:
}

Dan
--
Dan Pop
CERN, IT Division

Mail:  CERN - IT, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland


Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?

Quote:
>Good morning,
>The following piece of code is not intended to do something
>meaningful, I just want to know if there is any statement in it
>which breaks the rules (and why it does so).
>I have put comments before the lines I am especially interested.
>I wuold really appreciate your comments and thank you in advance for
>spending your time on that
>Robert

>#include <stdio.h>
>#include <malloc.h>
>#include <memory.h>

>struct s
>{
>    int a;
>    unsigned int b;
>    long c;
>    unsigned long d;
>    float e;

The use of float is not recommended, but it doesn't "break the rules"

- Show quoted text -

Quote:
>    double f;
>    char *g;
>    void *h;
>};

>int main(void)
>{
>    void *pv;
>    char *pc;
>    struct s *ps;
>    unsigned int i;

>/*I think the following 7 lines are ok. I am malloc()ing some space
>and initializing it to 0, and I am dealing with a pointer to void
>throughout*/

>    pv=malloc((int)sizeof(struct s));
>    if(pv==NULL)
>    {
>        printf("Malloc failed on pv\n");
>        return 1;

The standard return values for main are
0
EXIT_FAILURE
EXIT_SUCCESS
The latter are defined in <stdlib.h>

Quote:
>    }
>    memset(pv,0,(int)sizeof(struct s));

    memset(pv, 0, sizeof (struct s));
is nice too.

Quote:
>/*casting a void pointer to a char pointer is allowed AFAIK,

Yes, but setting data with memset() is only portable with chars (thanks
Dan). All depence on the typecast you will apply to pv.

Quote:
>assigning values to the array-elements also (please correct me if I
>am wrong)*/

>    pc=(char *)pv;

Ok, *pc is 0 because it is a char.

Quote:
>    for(i=0; i<(int)sizeof(struct s); i++)

Correct, but rather than using an int (or is it an unsigned int, you code is
unclear) for i, better to use a size_t which is the exact type of a sizeof.
Also, why is 'i' defined so far? It took me 5 precious seconds to find its
definition!

   {
   size_t i;
    for(i=0; i< sizeof(struct s); i++)

Quote:
>    {
>        pc[i]='0';
>    }

   }

Quote:
>/*ok, now I am casting the void pointer to a pointer to a struct
>containing int, long, floats, doubles and pointers. I think this
>should not do any harm as long as I consider the struct still
>uninitialized. I do not use any of the members nor do I dereference
>one of the pointers. Im I right here?*/

>    ps=(struct s *)pv;

Ok

Quote:
>/*now I assign (hopefully ;)) correct values to all of the members*/

>    ps->a=-1;
>    ps->b=1;
>    ps->c=-1L;
>    ps->d=1L;
>    ps->e=(float)1.5;
>    ps->f=1.5;
>    ps->g=malloc(10);
>    if(ps->g==NULL)
>    {
>        printf("Malloc failed on ps->g\n");
>        return 1;
>    }
>    memset(ps->g,'a',10);

will ps->g be used as a char array ?

Quote:
>    ps->h=malloc(10);
>    if(ps->h==NULL)
>    {
>        printf("Malloc failed on ps->h\n");
>        return 1;
>    }
>    memset(ps->h,'b',10);

will ps->h be used as a char array ?

Quote:
>    memcpy(ps->g,(const void *)ps->h,10);
>    return 0;
>} // main

>/*so - is there anything which violates the standard?*/

Not too bad.

Quote:
><off topic>
>I still don't know if my linelength is ok :( could you pls give me a
>feedback on that ?

Sounds correct to me and my newsreader...

Quote:
><end off topic>

--
-hs-    Tabs out, spaces in.
CLC-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
ISO-C Library: http://www.dinkum.com/htm_cl
FAQ de FCLC : http://www.isty-info.uvsq.fr/~rumeau/fclc
"Abracadabrantesque !" -- Jacques Chirac


Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?

Quote:

>>Good morning,
>>The following piece of code is not intended to do something
>>meaningful, I just want to know if there is any statement in it
>>which breaks the rules (and why it does so).
>>I have put comments before the lines I am especially interested.
>>I wuold really appreciate your comments and thank you in advance for
>>spending your time on that
>>Robert

>>#include <stdio.h>
>>#include <malloc.h>
>>#include <memory.h>

I didn't noticed that the first time, but these to last headers are not
standard.
You meant

#include <stdlib.h>

--
-hs-    Tabs out, spaces in.
CLC-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
ISO-C Library: http://www.dinkum.com/htm_cl
FAQ de FCLC : http://www.isty-info.uvsq.fr/~rumeau/fclc
"Abracadabrantesque !" -- Jacques Chirac



Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?

Quote:

> Good morning,
> The following piece of code is not intended to do something
> meaningful, I just want to know if there is any statement in it
> which breaks the rules (and why it does so).
> I have put comments before the lines I am especially interested.
> I wuold really appreciate your comments and thank you in advance for
> spending your time on that
> Robert

> #include <stdio.h>
> #include <malloc.h>

No such header. You probably meant to write #include <stdlib.h>

Quote:
> #include <memory.h>

No such header. You probably meant to write #include <string.h>

Quote:

> struct s
> {
>     int a;
>     unsigned int b;
>     long c;
>     unsigned long d;
>     float e;
>     double f;
>     char *g;
>     void *h;
> };

> int main(void)
> {
>     void *pv;
>     char *pc;
>     struct s *ps;
>     unsigned int i;

> /*I think the following 7 lines are ok. I am malloc()ing some space
> and initializing it to 0, and I am dealing with a pointer to void
> throughout*/

>     pv=malloc((int)sizeof(struct s));

malloc takes size_t, so the cast to int is a) futile and (b) potentially
a bug (although, if sizeof(struct s) is < 32 KB or so, you needn't
worry).

Better would be to pick up the return value of malloc in a struct s *
rather than a void *, in the general case, but it's not actually wrong
to pick it up in a void *.

Quote:
>     if(pv==NULL)
>     {
>         printf("Malloc failed on pv\n");
>         return 1;

When returning from main, return EXIT_FAILURE has portable semantics.
but return 1 does not.

Quote:
>     }
>     memset(pv,0,(int)sizeof(struct s));

Again, the cast is unnecessary.

Quote:

> /*casting a void pointer to a char pointer is allowed AFAIK,
> assigning values to the array-elements also (please correct me if I
> am wrong)*/

>     pc=(char *)pv;

Yes, this is legal; in fact, the cast is unnecessary.

Quote:
>     for(i=0; i<(int)sizeof(struct s); i++)

The cast is unnecessary. If you're getting a warning, you can silence it
by making i's type size_t. After all, that's what you're using it for.

Quote:
>     {
>         pc[i]='0';
>     }

You could have used calloc to achieve the same effect.

Quote:

> /*ok, now I am casting the void pointer to a pointer to a struct
> containing int, long, floats, doubles and pointers. I think this
> should not do any harm as long as I consider the struct still
> uninitialized. I do not use any of the members nor do I dereference
> one of the pointers. Im I right here?*/

Yes, I think so.

Quote:

>     ps=(struct s *)pv;

Again, the cast is unnecessary.

Quote:

> /*now I assign (hopefully ;)) correct values to all of the members*/

>     ps->a=-1;
>     ps->b=1;
>     ps->c=-1L;
>     ps->d=1L;
>     ps->e=(float)1.5;
>     ps->f=1.5;
>     ps->g=malloc(10);
>     if(ps->g==NULL)
>     {
>         printf("Malloc failed on ps->g\n");
>         return 1;

Again, think hard about this return value.

Why not free(pv) first, before quitting main()?

Quote:
>     }
>     memset(ps->g,'a',10);
>     ps->h=malloc(10);
>     if(ps->h==NULL)
>     {
>         printf("Malloc failed on ps->h\n");
>         return 1;
>     }
>     memset(ps->h,'b',10);
>     memcpy(ps->g,(const void *)ps->h,10);
>     return 0;
> } // main

> /*so - is there anything which violates the standard?*/

Well, apart from those headers and the return thing, I couldn't see
anything terribly wrong.

Quote:
> <off topic>
> I still don't know if my linelength is ok :( could you pls give me a
> feedback on that ?

It's about right.

--
Richard Heathfield
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
66 K&R Answers: http://users.powernet.co.uk/eton/kandr2/index.html (31
to go)



Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?
Richard Heathfield a crit dans le message

Quote:
>>     {
>>         pc[i]='0';
>>     }

>You could have used calloc to achieve the same effect.

I am not sure

'0' is not '\0' ;-)

--
-hs-    Tabs out, spaces in.
CLC-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
ISO-C Library: http://www.dinkum.com/htm_cl
FAQ de FCLC : http://www.isty-info.uvsq.fr/~rumeau/fclc
"Abracadabrantesque !" -- Jacques Chirac



Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?
Dan Pop schrieb:

Quote:
> Plenty of them!

> >#include <stdio.h>
> >#include <malloc.h>
> >#include <memory.h>

Thank you, I'll learn that by heart and set up my compiler in the
correct way when I am using pure c code
(err - if I can manage..)

Quote:

> >/*I think the following 7 lines are ok.

> You're way too optimistic :-)

> >    pv=malloc((int)sizeof(struct s));

> Not technically wrong, but plain silly.

Aaarrgghh, i tried to be too clever instead of reading the
documentation :(

Quote:

> Error messages are supposed to be sent to stderr, not to stdout.

I'll do that in the future :)

Quote:
> >        return 1;

> The proper method of reporting failure is to use EXIT_FAILURE, defined in
> <stdlib.h>.  For all you know, 1 might mean successful termination.

Hmm - normally I am using different return values (from an enum) for
different error conditions - is that wrong?

Quote:
> >    }
> >    memset(pv,0,(int)sizeof(struct s));

> The same comment as above about the cast to int.  The third argument of
> memset has type size_t.

> You could have achieved the effect of the memset call by allocating the
> memory with calloc instead of malloc.

Of course. Here I wanted to see if I am allowed to:
-allocate memory
-use it with a certain type
-change it's pointer type
-reinitialize it with data of the new type
-use it with the new type
therefore the explicit memset, just to make visible i did something
with the allocated space

Quote:

> >/*casting a void pointer to a char pointer is allowed AFAIK,

> >    for(i=0; i<(int)sizeof(struct s); i++)

> What do you need the cast to int for?  Especially since i is defined as
> unsigned int!

same as above, tried to be too clever :)

Quote:

> >    {
> >        pc[i]='0';
> >    }

> Technically correct, but useless as an initialisation.  Not a single
> field of your struct will be properly initialised by this loop.

Hmm, that is the point - I am not yet using that memory as a struct,
it is still an array of chars. I wanted to know if I am allowed to:
do whatever is legal for an array of chars with that block of
memory, write to it, read it back, use it for string manipulation
etc,
and when I am done with it, casting the pointer to a different type,
reinitialize and so on,
_or_
if I had to free() the block and malloc() another one

(i'd hardly do that in real life - just was curious)

Quote:

> The preferred form is:

>     ps->e = 1.5f;

Thanks, will use that in the future, it looks really better

Quote:

> >    memcpy(ps->g,(const void *)ps->h,10);

> The cast is unnecessary.

> You should really "hide" the constant 10 behind a macro in real code.

I do in real life, I use malloc()/realloc() mostly for variable size
arrays, getting the necessary size from somewhere as a variable

Quote:

> >    return 0;
> >} // main

> Unless you have a C99 compiler, the // comments are a syntax error in C.

uh, I have a bastard ;)

Thank you a lot for the corrected code
Kind regards
Robert



Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?
-hs- schrieb:

Quote:


> The use of float is not recommended, but it doesn't "break the rules"

That is what I wanted to know

Quote:

> The standard return values for main are
> 0
> EXIT_FAILURE
> EXIT_SUCCESS

Hmm, do the rules forbid using different return values for different
kinds of errors? That's what I do in real life: return 0 of all is
ok, and a nonzero number depending on what went wrong

Quote:

>     memset(pv, 0, sizeof (struct s));
> is nice too.

I tried to be too clever :(

Quote:

> >    for(i=0; i<(int)sizeof(struct s); i++)

> Correct, but rather than using an int (or is it an unsigned int, you code is
> unclear) for i, better to use a size_t which is the exact type of a sizeof.
> Also, why is 'i' defined so far? It took me 5 precious seconds to find its
> definition!

>    {
>    size_t i;
>     for(i=0; i< sizeof(struct s); i++)

Hmm, I was not sure, I thought this is not allowed prior to C99

Quote:
> >    memset(ps->h,'b',10);
> will ps->h be used as a char array ?

I will (in real life)

Thank you a lot for taking the effort and kind regards
Robert



Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?
-hs- schrieb:

Quote:



> >>Good morning,
> >>The following piece of code is not intended to do something
> >>meaningful, I just want to know if there is any statement in it
> >>which breaks the rules (and why it does so).
> >>I have put comments before the lines I am especially interested.
> >>I wuold really appreciate your comments and thank you in advance for
> >>spending your time on that
> >>Robert

> >>#include <stdio.h>
> >>#include <malloc.h>
> >>#include <memory.h>

> I didn't noticed that the first time, but these to last headers are not
> standard.
> You meant

> #include <stdlib.h>

Thank you, will correct that and (try to) setup my bastard compiler
correct

Quote:

> --
> -hs-    Tabs out, spaces in.
> CLC-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
> ISO-C Library: http://www.dinkum.com/htm_cl
> FAQ de FCLC : http://www.isty-info.uvsq.fr/~rumeau/fclc
> "Abracadabrantesque !" -- Jacques Chirac

Kind regards
Robert


Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?
Richard Heathfield schrieb:

I got that, will correct it and (if I can manage :() setup my
bastard compiler according

Quote:
> >     pv=malloc((int)sizeof(struct s));

> malloc takes size_t, so the cast to int is a) futile and (b) potentially
> a bug (although, if sizeof(struct s) is < 32 KB or so, you needn't
> worry).

I tried to bee too clever :(, thank you

Quote:

> Better would be to pick up the return value of malloc in a struct s *
> rather than a void *, in the general case, but it's not actually wrong
> to pick it up in a void *.

I did that, because later I am casting it to different types, so I
don't have to cast forward and back
(AFAIK only void to any type end any tpe to void is allowed)

Quote:
> >         return 1;

> When returning from main, return EXIT_FAILURE has portable semantics.
> but return 1 does not.

Is it forbidden? I ask because in real life i use several different
return values for different types of errors
<off topic>
This helps when I start my process from another one, the return
value from the create-function then tells me in more detail what was
wrong
<end off topic>

Quote:
> >     pc=(char *)pv;

> Yes, this is legal; in fact, the cast is unnecessary.

See above -I tried to be too clever..

Quote:
> >     {
> >         pc[i]='0';
> >     }

> You could have used calloc to achieve the same effect.

Not really '0' != 0 :) (you should see me dancing, one of the gurus
made a mistake - that makes me feel a little bit more intelligent
than a piece of plain white paper <grin>)

Quote:

> Why not free(pv) first, before quitting main()?

Oops, I forgot that. I also forgot to free() ps->g and ps->h, thank
you

Thank you for your hints and have a nice sunday
Kind regards
Robert



Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?


Quote:
> Good morning,
> The following piece of code is not intended to do something
> meaningful, I just want to know if there is any statement in it
> which breaks the rules (and why it does so).
> I have put comments before the lines I am especially interested.
> I wuold really appreciate your comments and thank you in advance for
> spending your time on that
> Robert

> #include <stdio.h>
> #include <malloc.h>
> #include <memory.h>

> struct s
> {
>     int a;
>     unsigned int b;
>     long c;
>     unsigned long d;
>     float e;
>     double f;
>     char *g;
>     void *h;
> };

> int main(void)
> {
>     void *pv;
>     char *pc;
>     struct s *ps;
>     unsigned int i;

> /*I think the following 7 lines are ok. I am malloc()ing some space
> and initializing it to 0, and I am dealing with a pointer to void
> throughout*/

>     pv=malloc((int)sizeof(struct s));
>     if(pv==NULL)
>     {
>         printf("Malloc failed on pv\n");
>         return 1;
>     }
>     memset(pv,0,(int)sizeof(struct s));

> /*casting a void pointer to a char pointer is allowed AFAIK,
> assigning values to the array-elements also (please correct me if I
> am wrong)*/

>     pc=(char *)pv;
>     for(i=0; i<(int)sizeof(struct s); i++)
>     {
>         pc[i]='0';
>     }

> /*ok, now I am casting the void pointer to a pointer to a struct
> containing int, long, floats, doubles and pointers. I think this
> should not do any harm as long as I consider the struct still
> uninitialized. I do not use any of the members nor do I dereference
> one of the pointers. Im I right here?*/

>     ps=(struct s *)pv;

> /*now I assign (hopefully ;)) correct values to all of the members*/

>     ps->a=-1;
>     ps->b=1;
>     ps->c=-1L;
>     ps->d=1L;
>     ps->e=(float)1.5;
>     ps->f=1.5;
>     ps->g=malloc(10);
>     if(ps->g==NULL)
>     {
>         printf("Malloc failed on ps->g\n");
>         return 1;
>     }
>     memset(ps->g,'a',10);
>     ps->h=malloc(10);
>     if(ps->h==NULL)
>     {
>         printf("Malloc failed on ps->h\n");
>         return 1;
>     }
>     memset(ps->h,'b',10);
>     memcpy(ps->g,(const void *)ps->h,10);
>     return 0;
> } // main

> /*so - is there anything which violates the standard?*/
> <off topic>
> I still don't know if my linelength is ok :( could you pls give me a
> feedback on that ?
> <end off topic>
> Thanks and kind regards
> Robert

There's nothing there that's wrong but there quite a lot there that is
confusing,
like setting pointer to all char '0' which is not valid. Also there can be
alignment bytes
to ensure that elements in the struct start on a valid memory address you
also initialize
those.

The same effect can be achieved in a simpler and less confusing manner.
All that you are trying to do is dynamically allocate a structure and
initialize it..
That can be better done like this:

#include <stdio.h>
#include <malloc.h>
#include <memory.h>

struct s
{
    int a;
    unsigned int b;
    long c;
    unsigned long d;
    float e;
    double f;
    char *g;
    void *h;

Quote:
};

int main(void)
{
    struct s *ps;

    ps= (struct s *) malloc((int)sizeof(struct s));
    if(ps==NULL)
    {
        printf("Malloc failed on ps\n");
        return 1;
    }

    ps->a=-1;
    ps->b=1;
    ps->c=-1L;
    ps->d=1L;
    ps->e=(float)1.5;
    ps->f=1.5;
    ps->g=malloc(10);
    if(ps->g==NULL)
    {
        printf("Malloc failed on ps->g\n");
        return 1;
    }
    memset(ps->g,'a',10);
    ps->h=malloc(10);
    if(ps->h==NULL)
    {
        printf("Malloc failed on ps->h\n");
        return 1;
    }
    memset(ps->h,'b',10);
    memcpy(ps->g,(const void *)ps->h,10);
    return 0;

Quote:
} // main

You may have a  problem in that your strings are not terminated, but that
might be your intention.
Also you call malloc several times without calling free. This leads to
memory leaks unless your system has a garbage collector.

Hope this helps.

John Castle.



Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?

Quote:
>> The standard return values for main are
>> 0
>> EXIT_FAILURE
>> EXIT_SUCCESS

>Hmm, do the rules forbid using different return values for different

No, it is only a portable issue.

Quote:
>kinds of errors? That's what I do in real life: return 0 of all is
>ok, and a nonzero number depending on what went wrong

In fact, it it depence your OS.

0, EXIT_FAILURE and EXIT_SUCCESS and guaranteed not to crash your OS. The
other values are OS-dependent. If one of them means "erase all data on
disks", it is not a C-issue.

Quote:
>> Also, why is 'i' defined so far? It took me 5 precious seconds to find
its
>> definition!

>>    {
>>    size_t i;
>>     for(i=0; i< sizeof(struct s); i++)

>Hmm, I was not sure, I thought this is not allowed prior to C99

In C, you can define a variable at the top of any block. C99 allows
definitions anywhere in a block. (I don't like it, probably because it
sounds like C++! Blech!)

Quote:
>Thank you a lot for taking the effort and kind regards

You're welcome.

--
-hs-    Tabs out, spaces in.
CLC-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
ISO-C Library: http://www.dinkum.com/htm_cl
FAQ de FCLC : http://www.isty-info.uvsq.fr/~rumeau/fclc
"Abracadabrantesque !" -- Jacques Chirac



Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?
John Castle schrieb:

Quote:

> There's nothing there that's wrong but there quite a lot there that is
> confusing,
> like setting pointer to all char '0' which is not valid. Also there can be

Sorry, John, I don't understand this point, could you pls clarify?

Quote:
> alignment bytes
> to ensure that elements in the struct start on a valid memory address you
> also initialize
> those.

> The same effect can be achieved in a simpler and less confusing manner.
> All that you are trying to do is dynamically allocate a structure and
> initialize it..

Ok, I see, my posting may have been misleading.
I actually wanted to know, if it is legal to allocate some space,
initialize and use it as a certain type
(char in my example, therefore the filling up with '0' btw, I can't
see what's wrong there), then, when I am done with it, cast the
pointer to a different type, treat the space as uninitiialized,
initialize it with the new type and use it as the new type (the
struct in my example)

Thank you for the hint with free() I really forgot them :(
Kind regards
Robert



Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?

Quote:
>Richard Heathfield schrieb:
>> >     {
>> >         pc[i]='0';
>> >     }

>> You could have used calloc to achieve the same effect.

>Not really '0' != 0 :) (you should see me dancing, one of the gurus
>made a mistake - that makes me feel a little bit more intelligent
>than a piece of plain white paper <grin>)

Richard told us himself he was not a guru! I think he is one of the most
experienced contributor in CLC, but like all of us he makes mistakes. That's
human.

--
-hs-    Tabs out, spaces in.
CLC-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
ISO-C Library: http://www.dinkum.com/htm_cl
FAQ de FCLC : http://www.isty-info.uvsq.fr/~rumeau/fclc
"Abracadabrantesque !" -- Jacques Chirac



Thu, 27 Mar 2003 03:00:00 GMT  
 is this valid code?
John Castle a crit dans le message

Quote:

>That can be better done like this:

>#include <stdio.h>
>#include <malloc.h>
>#include <memory.h>

What are the two latter?

#include <stdlib.h>

Quote:
>struct s
>{
>    int a;
>    unsigned int b;
>    long c;
>    unsigned long d;
>    float e;
>    double f;
>    char *g;
>    void *h;
>};

>int main(void)
>{
>    struct s *ps;

>    ps= (struct s *) malloc((int)sizeof(struct s));

     ps= malloc(sizeof(struct s));

Quote:
>    if(ps==NULL)
>    {
>        printf("Malloc failed on ps\n");
>        return 1;

        return EXIT_FAILURE;
Quote:
>    }

>    ps->a=-1;
>    ps->b=1;
>    ps->c=-1L;
>    ps->d=1L;
>    ps->e=(float)1.5;
>    ps->f=1.5;
>    ps->g=malloc(10);
>    if(ps->g==NULL)
>    {
>        printf("Malloc failed on ps->g\n");
>        return 1;

        return EXIT_FAILURE;
Quote:
>    }
>    memset(ps->g,'a',10);
>    ps->h=malloc(10);
>    if(ps->h==NULL)
>    {
>        printf("Malloc failed on ps->h\n");
>        return 1;
>    }
>    memset(ps->h,'b',10);
>    memcpy(ps->g,(const void *)ps->h,10);

    memcpy(ps->g, ps->h,10);

Quote:
>    return 0;
>} // main

--
-hs-    Tabs out, spaces in.
CLC-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
ISO-C Library: http://www.dinkum.com/htm_cl
FAQ de FCLC : http://www.isty-info.uvsq.fr/~rumeau/fclc
"Abracadabrantesque !" -- Jacques Chirac


Thu, 27 Mar 2003 03:00:00 GMT  
 
 [ 25 post ]  Go to page: [1] [2]

 Relevant Pages 

1. VC71 final beta - Reject valid C++ code snippet

2. Showing Call Stack and Determine which object is not valid LARGE CHUNK OF CODE

3. valid c code?

4. Who thinks this is valid C code?

5. Is this valid C++ code?

6. Is this valid code?

7. Please I am looking for sample code (C++ BUT NO MFC PLEASE)

8. Am I Assuming Too Much With This Code?

9. What am i doing wrong in this code?

10. Please look at this code n tell me where i am wrong

11. Code: What am I doing wrong?

12. Help-Assignment2// This time I am posting the code!!!Thanx

 

 
Powered by phpBB® Forum Software