Thread: Referencing and De-referencing Question

  1. #1
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489

    Question Referencing and De-referencing Question

    When we declare
    Code:
    int *a = NULL;
    "a" should be a pointer to an integer with nothing to point to (NULL).

    Code:
    int b = 1;
    and I think this statement is acceptable
    Code:
    a = &b;
    because now "a" is a pointer to an integer that point to value of "b"

    But,... What's happen here?
    Code:
    int c = 2;
    *a = b;
    I think this is illegal ( undefined behaviour, maybe? ) since "a" is pointing to nothing
    and there is no memory allocated for its value.

    Or 0 (NULL) has its own value?

    Code:
    #include "stdio.h"
    
    int main( int argc, char *argv[] ) {
    
      int *a = NULL;
      printf( "%d\n", a );
    
      int b = 1;
      a = &b;
      printf( "%d\n", *a ); // >> 1
    
      int c = 2;
      *a = c;
      printf( "%d\n", *a ); // >> 2 ??
    }
    Thanks in advance.
    Just GET it OFF out my mind!!

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    In your complete set of code at the end of the post, there is nothing wrong in that code, you show how you set b = c using indirection (a is pointing to b).

    I'm not quite sure what you are actually asking, beyond that.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Code:
    int *a = NULL;
    a is memory location which should contain another memory location. With this statement, you've set the contained memory location to 0, which is not a valid location in memory.

    Code:
    int b = 1;
    b is a memory location containing an integer.

    Code:
    a = &b;
    Because a contains a memory location, and the & operator returns a memory location, you've assigned a memory location -- a -- to point to b's memory location. Perfectly good.

    Code:
    int c = 2;
    *a = c;
    a currently has a valid memory location, so you're going to that memory location -- which contains the value in b -- and storing the value in memory location c there. Print b after and you'll see what I mean.

    If you had not previously assigned the address in a to the address of b, it would in fact be illegal.

  4. #4
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    Forgive me, please see them as separate code.

    Code:
    #include "stdio.h"
    
    int main( int argc, char *argv[] ) {
    
      int *a = NULL;
      printf( "%d\n", a );
    
      int c = 2;
      *a = c;
      printf( "%d\n", *a ); // >> 2 ??
    }
    Code:
    *a
    Dereferencing when "a" points to NULL?

    Code:
    *a = c;
    And then set its value to the value of "c"??

    Edit:
    If you had not previously assigned the address in a to the address of b, it would in fact be illegal.
    Ok, that's it! I got it. Thanks.
    Just GET it OFF out my mind!!

  5. #5
    Registered User
    Join Date
    Apr 2009
    Posts
    145
    Quote Originally Posted by audinue View Post
    But,... What's happen here?
    Code:
    int c = 2;
    *a = b;
    I think this is illegal ( undefined behaviour, maybe? ) since "a" is pointing to nothing
    and there is no memory allocated for its value.

    Or 0 (NULL) has its own value?

    [/code]Thanks in advance.
    Code:
    int main()
    {
             int  *a,b=2,c;
             *a = b;
             printf("*a = %d\n",*a);
             return 0;
    }
    
    Output:
    *a = 2
    Hope this clears your doubt?

  6. #6
    Registered User
    Join Date
    May 2007
    Posts
    147
    Code:
    #include "stdio.h"
    
    int main( int argc, char *argv[] ) {
    
      int *a = NULL;
      printf( "%d\n", a );    
    
      int b = 1;
      a = &b;
      printf( "%d\n", *a ); // >> 1
    
      int c = 2;
      *a = c;
      printf( "%d\n", *a ); // >> 2 ??
    }
    The first printf is an unfortunate use of printf, but it would work in most systems. "%d" assumes a signed integer, and if the size of an integer pointer is the same as the size of an integer, you'll see a zero printed - interpreting the address (set to null) AS an integer. I say unfortunate because if the size of an integer were different than the size of the pointer (which is possible is some systems), this could result in odd behavior.

    The second printf does what you expect. Dereferencing "a" results in the value stored in b.

    So, too, with the 3rd printf - in the context where a has been given the address of b (and so storage is available, a is no longer null), *a = c will also mean that b == 2.

    As to your question "what's happening here" - I just answered it, but let me break it down to be clear.

    "b" is a local variable, it is stored on the stack. The address of b will be a location on the stack, which is of minor importance limited to the scope of our discussion, but has other implications.

    a = &b;

    In this case, "a" is a pionter TO an integer, and after this statement it points to the location on the stack where b is stored (&b is taking the address of b). At this point "what's stored at 'a'" - or *a - is in fact what is stored in b - both a and b are operating on the same location in memory.

    such that *a = 3 will mean that what is stored in b will become 3, as if it were stated b = 3;

    It may also be of note that the code b = 3 generates assembler that is slightly smaller than *a = 3 in most cases. b = 3 is interpreted such that the compiler need only utilize the address of b and move the constant 3 into that location.

    On the other hand, *a = 3 cause the compiler to first must 'load' the address of a, a pointer, and then in a second step load what is stored there (the content of a), which is a pointer to an integer. It is this second value which is used to move the constant 3 into position, which in this discussion happens to be the same location where b is stored.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by sanddune008 View Post
    Code:
    int main()
    {
             int  *a,b=2,c;
             *a = b;
             printf("*a = %d\n",*a);
             return 0;
    }
    
    Output:
    *a = 2
    Hope this clears your doubt?
    Purely because you are lucky enough that the undefined value that a contains happens to be a piece of memory you can write to. The behaviour is undefined - it may launch nuclear missiles, or, more likely cause the system to crash. The trouble with undefined behaviour is that the compiler/environment is allowed to do ANYTHIGN IT LIKES - which also covers "whatever you may expect it to actually do" - it is UNDEFINED, not defined as "guaranteed to cause a crash".

    If you are using for example Turbo C, it is actually UNLIKELY to cause a (easily identifiable) crash - it will just do weird things, and if you keep doing bad stuff, it will sooner or later just hang.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed