Why would malloc() modify the behavior of this output?

Discussion in 'C Programming' started by grocery_stocker, May 11, 2005.

  1. If go like the following:

    #include <stdlib.h>

    void *test_me(int a) {
    int *m;
    m = &a;
    }

    main(void){
    char *j;

    j = test_me(1);

    printf("The value of j is : %x", *j);

    }

    I get:
    The value of j is : 1


    However, when I add malloc()

    #include <stdlib.h>

    void *test_me(int a) {
    int *m;
    m = &a;
    }

    main(void){
    char *p;
    char *j;

    p = malloc(10);
    j = test_me(1);

    printf("The value of p is : %x", *p);
    printf("The value of j is : %x", *j);

    free(p);
    }

    I get the following:
    The value of p is : 0
    The value of j is: ffffffc4

    Why does p become zero?
     
    grocery_stocker, May 11, 2005
    #1
    1. Advertising

  2. grocery_stocker

    Artie Gold Guest

    grocery_stocker wrote:
    > If go like the following:
    >
    > #include <stdlib.h>
    >
    > void *test_me(int a) {
    > int *m;
    > m = &a;


    Please notice that you're not returning anything from this function,
    though its signature indicates a pointer to void will be returned.
    Undefined behavior. All bets are off.

    > }
    >
    > main(void){
    > char *j;
    >
    > j = test_me(1);


    Again, since test_me() fails to return anything, the value of `j' is
    indeterminate.
    >
    > printf("The value of j is : %x", *j);
    >
    > }
    >
    > I get:
    > The value of j is : 1
    >
    >
    > However, when I add malloc()
    >
    > #include <stdlib.h>
    >
    > void *test_me(int a) {
    > int *m;
    > m = &a;
    > }
    >
    > main(void){
    > char *p;
    > char *j;
    >
    > p = malloc(10);
    > j = test_me(1);
    >
    > printf("The value of p is : %x", *p);
    > printf("The value of j is : %x", *j);
    >
    > free(p);
    > }
    >
    > I get the following:
    > The value of p is : 0
    > The value of j is: ffffffc4
    >
    > Why does p become zero?
    >

    Undefined behavior means the results could be *anything* -- even nasal
    demons might ensue.

    HTH,
    --ag

    --
    Artie Gold -- Austin, Texas
    http://it-matters.blogspot.com (new post 12/5)
    http://www.cafepress.com/goldsays
     
    Artie Gold, May 11, 2005
    #2
    1. Advertising

  3. grocery_stocker wrote:
    > If go like the following:
    >
    > #include <stdlib.h>
    >
    > void *test_me(int a) {
    > int *m;
    > m = &a;
    > }
    >
    > main(void){
    > char *j;
    >
    > j = test_me(1);
    >
    > printf("The value of j is : %x", *j);
    >
    > }
    >
    > I get:
    > The value of j is : 1
    >
    >
    > However, when I add malloc()
    >
    > #include <stdlib.h>
    >
    > void *test_me(int a) {
    > int *m;
    > m = &a;
    > }
    >
    > main(void){
    > char *p;
    > char *j;
    >
    > p = malloc(10);
    > j = test_me(1);
    >
    > printf("The value of p is : %x", *p);
    > printf("The value of j is : %x", *j);
    >
    > free(p);
    > }
    >
    > I get the following:
    > The value of p is : 0
    > The value of j is: ffffffc4
    >
    > Why does p become zero?
    >

    My guess is that after test_me has been called the stack is corrupt,
    since test_me returns an unspecified value, so p is probably modified by
    printf.
     
    August Karlstrom, May 11, 2005
    #3
  4. So in other words, when in the function test_me(), I should have used
    'static'?
     
    grocery_stocker, May 11, 2005
    #4
  5. Groovy hepcat grocery_stocker was jivin' on 10 May 2005 20:10:24 -0700
    in comp.lang.c.
    Why would malloc() modify the behavior of this output?'s a cool scene!
    Dig it!

    >If go like the following:
    >
    >#include <stdlib.h>
    >
    >void *test_me(int a) {
    >int *m;
    >m = &a;
    >}


    You should get a diagnostic here. You're not returning anything from
    this function. This is no doubt the cause of your problem.

    >main(void){


    int main(void)
    {

    .... to satisfy C99.

    >char *j;
    >
    >j = test_me(1);


    j now contains an indeterminate value, because you have failed to
    return a value from test_me().

    >printf("The value of j is : %x", *j);


    Since j is indeterminate, dereferencing it here causes undefined
    behaviour.

    return 0;

    .... to satisfy C90.

    >}
    >
    >I get:
    >The value of j is : 1


    It could be anything. For that matter, you needn't get any output at
    all. The program could crash. Or it could cause a shift in the
    space-time continuum which traps you in the 13th dimention. Undefined
    behaviour means that ANYTHING the program does is "right".

    >However, when I add malloc()
    >
    >#include <stdlib.h>
    >
    >void *test_me(int a) {
    >int *m;
    >m = &a;
    >}
    >
    >main(void){


    int main(void)
    {
    >char *p;
    >char *j;
    >
    >p = malloc(10);


    Check! Always check the return value of functions like malloc(). You
    must not try to dereference the pointer if malloc() fails.

    >j = test_me(1);
    >
    >printf("The value of p is : %x", *p);


    *p is uninitialised. Its value is indeterminate. p points to
    dynamically allocated memory IF the malloc() call succeeded. but the
    memory it points to has not been given a value.

    >printf("The value of j is : %x", *j);


    And once again the value of j is indeterminate, and you are causing
    undefined behaviour by dereferencing it.

    >free(p);


    return 0;
    >}
    >
    >I get the following:
    >The value of p is : 0
    >The value of j is: ffffffc4
    >
    >Why does p become zero?


    p does not become 0. *p, however, is indeterminate. It could be 0,
    but it could be anything else. It just happens to be 0 in this
    instance.

    --

    Dig the even newer still, yet more improved, sig!

    http://alphalink.com.au/~phaywood/
    "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
    I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
     
    Peter Shaggy Haywood, May 11, 2005
    #5
  6. grocery_stocker

    Artie Gold Guest

    grocery_stocker wrote:
    > So in other words, when in the function test_me(), I should have used
    > 'static'?
    >

    First of all, it is imperative in Usenet discussions to maintain enough
    context to know what you're talking about.

    And the answer is: The function test_me() needs to return something. It
    doesn't.

    HTH,
    --ag

    --
    Artie Gold -- Austin, Texas
    http://it-matters.blogspot.com (new post 12/5)
    http://www.cafepress.com/goldsays
     
    Artie Gold, May 11, 2005
    #6
  7. grocery_stocker

    Grumble Guest

    Peter Shaggy Haywood wrote:

    > It could be anything. For that matter, you needn't get any output at
    > all. The program could crash. Or it could cause a shift in the
    > space-time continuum which traps you in the 13th dimention. Undefined
    > behaviour means that ANYTHING the program does is "right".


    Mankind should try to harness the power of UB.

    It seems to have even more potential than nuclear fusion.
     
    Grumble, May 11, 2005
    #7
  8. grocery_stocker

    Richard Bos Guest

    Grumble <> wrote:

    > Peter Shaggy Haywood wrote:
    >
    > > It could be anything. For that matter, you needn't get any output at
    > > all. The program could crash. Or it could cause a shift in the
    > > space-time continuum which traps you in the 13th dimention. Undefined
    > > behaviour means that ANYTHING the program does is "right".

    >
    > Mankind should try to harness the power of UB.
    >
    > It seems to have even more potential than nuclear fusion.


    It does, but unfortunately this includes the power not to be harnessed.
    It is a bit like Mephistophilis in this way - people who try to harness
    the power of uninitialised objects tend to find themselves facing
    thunder and lightning at midnight, twenty-four years being expired.

    Richard
     
    Richard Bos, May 11, 2005
    #8
  9. "grocery_stocker" <> writes:
    [...]
    > printf("The value of j is : %x", *j);

    [...]
    > printf("The value of p is : %x", *p);
    > printf("The value of j is : %x", *j);


    Among numerous other errors, you're not printing the values of j and
    p. You're printing the values of *j and *p.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, May 11, 2005
    #9
  10. grocery_stocker

    Old Wolf Guest

    Peter "Shaggy" Haywood wrote:
    > Groovy hepcat grocery_stocker was jivin':
    > >
    > >#include <stdlib.h>
    > >
    > >void *test_me(int a) {
    > >int *m;
    > >m = &a;
    > >}

    >
    > You should get a diagnostic here. You're not returning
    > anything from this function. This is no doubt the cause
    > of your problem.


    No diagnostic is required for this situation.

    > int main(void)
    > {
    >
    > >char *j;
    > >
    > >j = test_me(1);

    >
    > j now contains an indeterminate value, because you have
    > failed to return a value from test_me().


    Actually the behaviour became undefined at the point of
    test_me() returning. So 'j' could contain any value
    (indeterminate or not), or nasal demons, or cease to exist, etc.

    > >printf("The value of j is : %x", *j);

    >
    > Since j is indeterminate, dereferencing it here
    > causes undefined behaviour.


    If j were indeterminate, merely mentioning it would cause
    undefined behaviour.
     
    Old Wolf, May 11, 2005
    #10
  11. grocery_stocker

    Al Bowers Guest

    grocery_stocker wrote:
    > So in other words, when in the function test_me(), I should have used
    > 'static'?
    >


    That could help matters because I assume this use of the
    static keyword is to deal with the function test_me reurning the
    address of a int that doesn't exist once the function returns.

    But there are numerous other errors. So many that I probably
    will miss some in my comments.

    The code fails to include header stdio.h.

    Function main returns a int.

    Tbe function test_me code does not return a value even though
    the prototype calls for a return of void *.

    You are attempting to convert a int * to void * to char *.
    This does not guarantee that the original pointer(to int *)
    will compare equal to the result(char *).
    If you converted it back again to int * (int * -> void * -< int *),
    the the standard says the result shall compare equal to the
    original pointer.

    If you rid all this UB then you will see that function
    malloc will have no affect on the test.

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

    void *test_me(int a)
    {
    static int m;
    m = a;
    return &m;
    }

    int main(void)
    {
    int *j, *i;

    j = test_me(1);
    printf("Test on function test-me before malloc\n"
    "The value of j is : %i\n"
    "The address of is %x\n\n", *j, (void *)j);
    i = malloc(10 * sizeof *i);
    printf( "Test on function test_me after malloc\n"
    "The value of j is : %d\n"
    "The address of is %x\n\n", *j, (void *)j);
    free(i);
    return 0;
    }


    --
    Al Bowers
    Tampa, Fl USA
    mailto: (remove the x to send email)
    http://www.geocities.com/abowers822/
     
    Al Bowers, May 11, 2005
    #11
  12. grocery_stocker

    Al Bowers Guest

    grocery_stocker wrote:

    > So in other words, when in the function test_me(), I should have used
    > 'static'?
    >


    That could help matters because I assume this use of the
    static keyword is to deal with the function test_me reurning the
    address of a int that doesn't exist once the function returns.

    But there are numerous other errors. So many that I probably
    will miss some in my comments.

    The code fails to include header stdio.h.

    Function main returns a int.

    Tbe function test_me code does not return a value even though
    the prototype calls for a return of void *.

    You are attempting to convert a int * to void * to char *.
    This does not guarantee that the original pointer(to int *)
    will compare equal to the result(char *).
    If you converted it back again to int * (int * -> void * -< int *),
    the the standard says the result shall compare equal to the
    original pointer.

    If you rid all this UB then you will see that function
    malloc will have no affect on the test.

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

    void *test_me(int a)
    {
    static int m;
    m = a;
    return &m;
    }

    int main(void)
    {
    int *j, *i;

    j = test_me(1);
    printf("Test on function test-me before malloc\n"
    "The value of j is : %d\n"
    "The address of is %p\n\n", *j, (void *)j);
    i = malloc(10 * sizeof *i);
    printf( "Test on function test_me after malloc\n"
    "The value of j is : %d\n"
    "The address of is %p\n\n", *j, (void *)j);
    free(i);
    return 0;
    }

    --
    Al Bowers
    Tampa, Fl USA
    mailto: (remove the x to send email)
    http://www.geocities.com/abowers822/
     
    Al Bowers, May 11, 2005
    #12
  13. On 11 May 2005 04:15:21 -0700, in comp.lang.c , "Old Wolf"
    <> wrote:

    >Peter "Shaggy" Haywood wrote:
    >> Groovy hepcat grocery_stocker was jivin':
    >> >
    >> >#include <stdlib.h>
    >> >
    >> >void *test_me(int a) {
    >> >int *m;
    >> >m = &a;
    >> >}

    >>
    >> You should get a diagnostic here. You're not returning
    >> anything from this function. This is no doubt the cause
    >> of your problem.

    >
    >No diagnostic is required for this situation.


    possibly, but any decent compiler should emit one anyway.

    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
     
    Mark McIntyre, May 11, 2005
    #13
  14. grocery_stocker

    pete Guest

    Lawrence Kirby wrote:
    >
    > On Wed, 11 May 2005 12:16:11 -0400, Al Bowers wrote:
    >
    > ...
    >
    > > You are attempting to convert a int * to void * to char *.
    > > This does not guarantee that the original pointer(to int *)
    > > will compare equal to the result(char *).

    >
    > In order to compare values they have to be of the same type. Once you
    > ensure that the situation changes.
    >
    > One of the main probmes with the original code
    > is the incorrect way that
    > it attempts to convert the values of pointers (presuming that was
    > intended). Your version fixes that.
    >
    > > If you converted it back again to int * (int * -> void * -< int *),
    > > the the standard says the result shall compare equal to the
    > > original pointer.

    >
    > In this case there's int * -> void * -> char * vs. int * -> char *.
    > Given that void * has the same representation as pointers
    > to character types it
    > is difficult to see how these conversion sequences
    > could produce unequal results from a valid initial value.


    There's also that
    a pointer to an object, converted to (char *),
    becomes a pointer to the lowest addressable byte of the object.
    So, even if a (void *) pointer
    didn't have any special relation to (char *),
    converting a (void *) to (char *),
    should yield the address of the lowest addressable byte
    of whatever object the (void *) pointer has the address of.

    For
    int object;
    (char *)&object is the address of the lowest addressable byte of object.
    (char *)(void *)&object, should be the address of the same byte.

    I don't think pointer representation is an issue here.

    --
    pete
     
    pete, May 12, 2005
    #14
  15. On Wed, 11 May 2005 12:16:11 -0400, Al Bowers wrote:

    ....

    > You are attempting to convert a int * to void * to char *.
    > This does not guarantee that the original pointer(to int *)
    > will compare equal to the result(char *).


    In order to compare values they have to be of the same type. Once you
    ensure that the situation changes.

    One of the main probmes with the original code is the incorrect way that
    it attempts to convert the values of pointers (presuming that was
    intended). Your version fixes that.

    > If you converted it back again to int * (int * -> void * -< int *),
    > the the standard says the result shall compare equal to the
    > original pointer.


    In this case there's int * -> void * -> char * vs. int * -> char *. Given
    that void * has the same representation as pointers to character types it
    is difficult to see how these conversion sequences could produce unequal
    results from a valid initial value.

    Lawrence
     
    Lawrence Kirby, May 12, 2005
    #15
    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. Vikram
    Replies:
    9
    Views:
    290
    Karl Heinz Buchegger
    May 17, 2005
  2. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    909
    Mark Rae
    Dec 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,998
    Smokey Grindel
    Dec 2, 2006
  4. John
    Replies:
    13
    Views:
    708
  5. ravi
    Replies:
    0
    Views:
    455
Loading...

Share This Page