Structures and Pointers

Discussion in 'C Programming' started by Sally, Jun 10, 2004.

  1. Sally

    Sally Guest

    I am confused as to why the code below does not produce a segmenation
    fault. It actually works, and I get 12 outputted on my screen. I
    would have thought I needed to get memory using malloc?

    I noticed also if I do use malloc, then free(ptr), I can still use
    ptr->z and assign to z successfully?

    struct myStruct {
    char x[10];
    char y[1000];
    int z;
    };

    int main(..) {

    struct myStruct *ptr;

    ptr->z = 12;
    printf("%d",prt->z);

    }
    Sally, Jun 10, 2004
    #1
    1. Advertising

  2. Sally <> scribbled the following:
    > I am confused as to why the code below does not produce a segmenation
    > fault. It actually works, and I get 12 outputted on my screen. I
    > would have thought I needed to get memory using malloc?


    It works by accident. The code invokes undefined behaviour, but
    undefined behaviour does not automatically mean segmentation
    faults. If you try it in different circumstances, it might very well
    crash.

    > I noticed also if I do use malloc, then free(ptr), I can still use
    > ptr->z and assign to z successfully?


    The same reasoning applies.

    > struct myStruct {
    > char x[10];
    > char y[1000];
    > int z;
    > };


    > int main(..) {


    > struct myStruct *ptr;


    > ptr->z = 12;
    > printf("%d",prt->z);


    > }


    --
    /-- Joona Palaste () ------------- Finland --------\
    \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
    "It's not survival of the fattest, it's survival of the fittest."
    - Ludvig von Drake
    Joona I Palaste, Jun 10, 2004
    #2
    1. Advertising

  3. Sally

    Mike Wahler Guest

    "Sally" <> wrote in message
    news:...
    > I am confused as to why the code below does not produce a segmenation
    > fault.


    It's not required to.

    > It actually works


    By (unfortunate) accident. This time.

    > and I get 12 outputted on my screen. I
    > would have thought I needed to get memory using malloc?


    You do if you want your program's behavior to be
    well-defined and predictable, with guarantees from
    the language standard about its behavior.

    > I noticed also if I do use malloc, then free(ptr), I can still use
    > ptr->z and assign to z successfully?
    >
    > struct myStruct {
    > char x[10];
    > char y[1000];
    > int z;
    > };
    >
    > int main(..) {
    >
    > struct myStruct *ptr;
    >
    > ptr->z = 12;
    > printf("%d",prt->z);
    >
    > }


    The above is an example of 'undefined behavior'. According to
    the language standard, the compiler is allowed to produce
    code that does *anything*. This can vary from a violent
    crash, to 'seeming to work' (and theoretically such things
    as the ubiquitous 'nasal demons'). In your case, it 'seems
    to work.' Next time it might do something completely different.
    Murphy's law dictates that this will happen when the application
    is first demonstrated to a potential client.

    Moral: Don't Do That.

    You also have another case of undefined behavior:
    invocation of 'printf()' with no prototype in scope.

    And you need a return statement for main().

    -Mike
    Mike Wahler, Jun 10, 2004
    #3
  4. (Sally) wrote in
    news::

    > I am confused as to why the code below does not produce a segmenation
    > fault. It actually works, and I get 12 outputted on my screen. I
    > would have thought I needed to get memory using malloc?


    You got (un)lucky. You do need to use malloc() in this case. What you did
    is wrong.

    > I noticed also if I do use malloc, then free(ptr), I can still use
    > ptr->z and assign to z successfully?


    Again, do not do this. If it works as hoped it's just luck.

    > struct myStruct {
    > char x[10];
    > char y[1000];
    > int z;
    > };
    >
    > int main(..) {
    >
    > struct myStruct *ptr;
    >
    > ptr->z = 12;


    Do *not* do this.

    > printf("%d",prt->z);
    >
    > }
    >




    --
    - Mark ->
    --
    Mark A. Odell, Jun 10, 2004
    #4
  5. Sally

    Joe Laughlin Guest

    Mike Wahler wrote:
    > "Sally" <> wrote in message
    > news:...
    >> I am confused as to why the code below does not produce
    >> a segmenation fault.

    >
    > It's not required to.
    >
    >> It actually works

    >
    > By (unfortunate) accident. This time.
    >
    >> and I get 12 outputted on my screen. I
    >> would have thought I needed to get memory using malloc?

    >
    > You do if you want your program's behavior to be
    > well-defined and predictable, with guarantees from
    > the language standard about its behavior.
    >
    >> I noticed also if I do use malloc, then free(ptr), I can
    >> still use ptr->z and assign to z successfully?
    >>
    >> struct myStruct {
    >> char x[10];
    >> char y[1000];
    >> int z;
    >> };
    >>
    >> int main(..) {
    >>
    >> struct myStruct *ptr;
    >>
    >> ptr->z = 12;
    >> printf("%d",prt->z);
    >>
    >> }

    >
    >

    <snip>
    > You also have another case of undefined behavior:
    > invocation of 'printf()' with no prototype in scope.
    >


    You need to include a prototype for each function that you use?
    Joe Laughlin, Jun 10, 2004
    #5
  6. Joe Laughlin <> scribbled the following:
    > Mike Wahler wrote:
    >> "Sally" <> wrote in message
    >> news:...
    >>> I am confused as to why the code below does not produce
    >>> a segmenation fault.

    >>
    >> It's not required to.
    >>
    >>> It actually works

    >>
    >> By (unfortunate) accident. This time.
    >>
    >>> and I get 12 outputted on my screen. I
    >>> would have thought I needed to get memory using malloc?

    >>
    >> You do if you want your program's behavior to be
    >> well-defined and predictable, with guarantees from
    >> the language standard about its behavior.
    >>
    >>> I noticed also if I do use malloc, then free(ptr), I can
    >>> still use ptr->z and assign to z successfully?
    >>>
    >>> struct myStruct {
    >>> char x[10];
    >>> char y[1000];
    >>> int z;
    >>> };
    >>>
    >>> int main(..) {
    >>>
    >>> struct myStruct *ptr;
    >>>
    >>> ptr->z = 12;
    >>> printf("%d",prt->z);
    >>>
    >>> }

    >>

    > <snip>
    >> You also have another case of undefined behavior:
    >> invocation of 'printf()' with no prototype in scope.


    > You need to include a prototype for each function that you use?


    Yes, you do. In C99 at least. A full definition constitutes a
    prototype, however a mere declaration does not always do so.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
    "Remember: There are only three kinds of people - those who can count and those
    who can't."
    - Vampyra
    Joona I Palaste, Jun 10, 2004
    #6
  7. Sally

    Sam Dennis Guest

    Joe Laughlin wrote:
    > Mike Wahler wrote:
    >> You also have another case of undefined behavior:
    >> invocation of 'printf()' with no prototype in scope.

    >
    > You need to include a prototype for each function that you use?


    No, but you do need to for all variadic functions. It's a good idea
    regardless, however.

    --
    ++acr@,ka"
    Sam Dennis, Jun 10, 2004
    #7
  8. "Joe Laughlin" <> wrote in message
    news:...
    > Mike Wahler wrote:
    > > "Sally" <> wrote in message
    > > news:...
    > >> I am confused as to why the code below does not produce
    > >> a segmenation fault.

    > >
    > > It's not required to.
    > >
    > >> It actually works

    > >
    > > By (unfortunate) accident. This time.
    > >
    > >> and I get 12 outputted on my screen. I
    > >> would have thought I needed to get memory using malloc?

    > >
    > > You do if you want your program's behavior to be
    > > well-defined and predictable, with guarantees from
    > > the language standard about its behavior.
    > >
    > >> I noticed also if I do use malloc, then free(ptr), I can
    > >> still use ptr->z and assign to z successfully?
    > >>
    > >> struct myStruct {
    > >> char x[10];
    > >> char y[1000];
    > >> int z;
    > >> };
    > >>
    > >> int main(..) {
    > >>
    > >> struct myStruct *ptr;
    > >>
    > >> ptr->z = 12;
    > >> printf("%d",prt->z);
    > >>
    > >> }

    > >
    > >

    > <snip>
    > > You also have another case of undefined behavior:
    > > invocation of 'printf()' with no prototype in scope.
    > >

    >
    > You need to include a prototype for each function that you use?
    >


    The way you worded this question leads me to believe you may not be aware of
    the fact that "#include <stdio.h>" brings a prototype for printf() into
    scope. You do not need to manually prototype every standard library function
    you call, just include the appropriate header.

    >
    >
    Kieran Simkin, Jun 10, 2004
    #8
  9. Sally

    Default User Guest

    Sally wrote:
    >
    > I am confused as to why the code below does not produce a segmenation
    > fault. It actually works, and I get 12 outputted on my screen. I
    > would have thought I needed to get memory using malloc?



    You've learned a valuable lesson, don't rely on your implementation to
    catch your mistakes in a predictable way.



    Brian Rodenborn
    Default User, Jun 10, 2004
    #9
  10. Sally

    Joe Laughlin Guest

    Kieran Simkin wrote:
    > "Joe Laughlin" <> wrote in
    > message news:...
    >> Mike Wahler wrote:
    >>> "Sally" <> wrote in message
    >>> news:...
    >>>> I am confused as to why the code below does not produce
    >>>> a segmenation fault.
    >>>
    >>> It's not required to.
    >>>
    >>>> It actually works
    >>>
    >>> By (unfortunate) accident. This time.
    >>>
    >>>> and I get 12 outputted on my screen. I
    >>>> would have thought I needed to get memory using malloc?
    >>>
    >>> You do if you want your program's behavior to be
    >>> well-defined and predictable, with guarantees from
    >>> the language standard about its behavior.
    >>>
    >>>> I noticed also if I do use malloc, then free(ptr), I
    >>>> can still use ptr->z and assign to z successfully?
    >>>>
    >>>> struct myStruct {
    >>>> char x[10];
    >>>> char y[1000];
    >>>> int z;
    >>>> };
    >>>>
    >>>> int main(..) {
    >>>>
    >>>> struct myStruct *ptr;
    >>>>
    >>>> ptr->z = 12;
    >>>> printf("%d",prt->z);
    >>>>
    >>>> }
    >>>
    >>>

    >> <snip>
    >>> You also have another case of undefined behavior:
    >>> invocation of 'printf()' with no prototype in scope.
    >>>

    >>
    >> You need to include a prototype for each function that
    >> you use?
    >>

    >
    > The way you worded this question leads me to believe you
    > may not be aware of the fact that "#include <stdio.h>"
    > brings a prototype for printf() into scope. You do not
    > need to manually prototype every standard library
    > function you call, just include the appropriate header.


    Oh, yeah. Nevermind. :)
    Joe Laughlin, Jun 11, 2004
    #10
  11. Sally

    Ben Pfaff Guest

    Joona I Palaste <> writes:

    > Joe Laughlin <> scribbled the following:
    >> You need to include a prototype for each function that you use?

    >
    > Yes, you do. In C99 at least. A full definition constitutes a
    > prototype, however a mere declaration does not always do so.


    You are confused. C99 requires called functions to be declared.
    It does not require prototypes for called functions. A full
    definition may not include a prototype, because it can be a K&R
    style definition[1], but it is always a declaration.

    [1] C99 has still not outlawed these (which it calls "function
    declarators with empty parentheses (not prototype-format
    parameter type declarators)"), although they have been obsolete
    since C89, and it seems likely that they will be in C0x too.
    --
    "The lusers I know are so clueless, that if they were dipped in clue
    musk and dropped in the middle of pack of horny clues, on clue prom
    night during clue happy hour, they still couldn't get a clue."
    --Michael Girdwood, in the monastery
    Ben Pfaff, Jun 11, 2004
    #11
  12. On Thu, 10 Jun 2004 18:14:43 -0700, in comp.lang.c , Ben Pfaff
    <> wrote:

    >Joona I Palaste <> writes:
    >
    >> Joe Laughlin <> scribbled the following:
    >>> You need to include a prototype for each function that you use?

    >>
    >> Yes, you do. In C99 at least. A full definition constitutes a
    >> prototype, however a mere declaration does not always do so.

    >
    >You are confused. C99 requires called functions to be declared.
    >It does not require prototypes for called functions. A full
    >definition may not include a prototype, because it can be a K&R
    >style definition[1], but it is always a declaration.


    ISTR that C99 is a little stricter about when a function call has invoked
    UB than C89 was. However I'm not entirely clear about where that is in the
    standard.

    >[1] C99 has still not outlawed these


    But its made it pretty darn clear you should not use them (6.11.6 and
    6.11.7).
    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>


    ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
    ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---


    ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
    ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
    Mark McIntyre, Jun 11, 2004
    #12
  13. Sally

    Ben Pfaff Guest

    Mark McIntyre <> writes:

    > On Thu, 10 Jun 2004 18:14:43 -0700, in comp.lang.c , Ben Pfaff
    > <> wrote:
    >
    >>Joona I Palaste <> writes:
    >>
    >>> Joe Laughlin <> scribbled the following:
    >>>> You need to include a prototype for each function that you use?
    >>>
    >>> Yes, you do. In C99 at least. A full definition constitutes a
    >>> prototype, however a mere declaration does not always do so.

    >>
    >>You are confused. C99 requires called functions to be declared.
    >>It does not require prototypes for called functions. A full
    >>definition may not include a prototype, because it can be a K&R
    >>style definition[1], but it is always a declaration.

    >
    > ISTR that C99 is a little stricter about when a function call has invoked
    > UB than C89 was. However I'm not entirely clear about where that is in the
    > standard.


    You'll have to be specific. I'm not aware of the changes you're
    describing, nor do I even vaguely remember something like that.

    Both C89 and C99 do require prototypes for variadic functions.

    >>[1] C99 has still not outlawed these

    >
    > But its made it pretty darn clear you should not use them (6.11.6 and
    > 6.11.7).


    That wording is unchanged from C89.
    --
    "Given that computing power increases exponentially with time,
    algorithms with exponential or better O-notations
    are actually linear with a large constant."
    --Mike Lee
    Ben Pfaff, Jun 12, 2004
    #13
  14. On Sat, 12 Jun 2004 11:03:47 -0700, in comp.lang.c , Ben Pfaff
    <> wrote:

    >Mark McIntyre <> writes:
    >
    >>
    >> ISTR that C99 is a little stricter about when a function call has invoked
    >> UB than C89 was. However I'm not entirely clear about where that is in the
    >> standard.

    >
    >You'll have to be specific. I'm not aware of the changes you're
    >describing, nor do I even vaguely remember something like that.


    *grin*. I can't be more specific, because I can't remember where it is. I
    was kinda hoping someone else would remember. Or disremember and correct
    me. Either is acceptable.

    (of K&R style)
    >>>[1] C99 has still not outlawed these

    >>
    >> But its made it pretty darn clear you should not use them (6.11.6 and
    >> 6.11.7).

    >
    >That wording is unchanged from C89.


    Sure, and I think that C89 made it perfectly clear that one should not
    write that style. Repeating the lesson a decade later reinforces the point,
    just don't do it.....

    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>


    ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
    ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---


    ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
    ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
    Mark McIntyre, Jun 14, 2004
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    7
    Views:
    411
  2. Neil Zanella
    Replies:
    9
    Views:
    406
    Jeffrey D. Smith
    Oct 16, 2003
  3. tweak
    Replies:
    14
    Views:
    2,760
    Eric Sosman
    Jun 11, 2004
  4. Alfonso Morra
    Replies:
    11
    Views:
    701
    Emmanuel Delahaye
    Sep 24, 2005
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    651
Loading...

Share This Page