Thread: Pointer headache

  1. #1
    Registered User
    Join Date
    May 2002
    Posts
    85

    Question Pointer headache

    Dear all Sir:
    I am confused between Legal address and none-Legal
    address POINTER. For example below:

    int a;
    int *pt = NULL; /* pt does not hold a legal address */
    int *q = &a; /* q hold a legal address */

    printf("address of pt is %p", pt);
    printf("address of a is %p", &a);
    printf("address of q is %p", q);

    But when run this code segment, pt holds a perfect memory address. Why many books say that the case
    int *pt = NULL hold none-legal address?
    In this scenerio, What non-legal address mean?
    Any C experts can explain concisely about this.
    Thanx for a million.
    DV007

  2. #2
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    it isnt a legal address. I'm curious what you get when you run this program

  3. #3
    Green Member Cshot's Avatar
    Join Date
    Jun 2002
    Posts
    892
    pt holds a NULL address(it'll most likely output a 0). You will get unexpected results if you try to mess with that address because it's not a legal one meaning it's not for your use.

    q holds a legal address since it stores the address of a. Int a was allocated by your program therefore it is legal and safe to use that location up to sizeof(int).

  4. #4
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >But when run this code segment, pt holds a perfect memory address.
    What's a "perfect memory address"? As already stated, it will hold NULL.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  5. #5
    Registered User
    Join Date
    May 2002
    Posts
    85
    Originally posted by Cshot
    pt holds a NULL address(it'll most likely output a 0). You will get unexpected results if you try to mess with that address because it's not a legal one meaning it's not for your use.

    q holds a legal address since it stores the address of a. Int a was allocated by your program therefore it is legal and safe to use that location up to sizeof(int).
    Thanx for your explaining, Cshot.
    I have one more question that what about int *ptr?
    does int *ptr holds non-legal address too?
    int *ptr; /* a none initialize pointer */

    DV007

  6. #6
    Sayeh
    Guest
    Okay, okay, let's get our head around 'compiler jargon' a little bit. The confusion is in the way you are looking at the terms.

    Remember, C/C++ is written according to specific grammar rules. This is called 'syntax'.

    When the compiler says 'non-legal' address it means that it is an address that is effectively 'out of bounds' for your use. Either no such physical/virtual address of that value is accessible, or you are trying to access something on 'zero page' (low RAM where the O/S works).

    Using your example:

    Code:
    int a; 
    int *pt = NULL;    /* pt does not hold a legal address */ 
    int *q = &a;         /* q hold a legal address */
    When you declare 'a', upon execution, the space for this integer variable is determined and known. Let's just say that 'a' is an integer (2-bytes) worth of RAM at location 0x00315D3A.

    Like so:

    Code:
    Address      Bytes
    -------------------------------------------------------------------------------------------------
    00315D3A  00 00                                      <-- 2 bytes (16 bits)
    00315D3C  EF 31 D4 55 3A B2 32 61        <-- RAM with random values
    00315D44  00 00 2D 01 00 3A DD 74        <-- RAM with more random values.
    When you say 'int *pt = NULL', you are stuffing a zero (long) into 'pt'. This is a valid value. If you poke anything into location zero it RAM, either the O/S won't allow you to (protected memory), or you will screw something up (scrambling valid data already there). It is an illegal address because you're not supposed to access it, but it's a valid value, so the program will still run, although the compiler gives you a warning.

    When you say 'int *q = &a', of course this is legal because &a = 0x00315D3A, so 'q' now points to that location in RAM.

    Any value might be at that location, until _you_ specifically initialize it something difference (such as with q[0] = 0x0000.

  7. #7
    Registered User
    Join Date
    May 2002
    Posts
    85
    Thanks for your expertised explaining, Sayeh.
    but how about a non-initialized pointer?
    For example:

    int *iptr; /* these are non-initialized pointer
    float *fptr; /* variables and I guess non-legal*/

    printf("address of iptr is: %p ", iptr);
    printf("address of fptr is: %p", fptr);

    Since base on C books,both above pointer variables
    hold non-legal addresses. But actually it outputs
    perfect address for both. Each pointer hold a
    different perfect 32-bit address on my PC. So why C called them "illegal" addresspointers?
    Code:
     
                              _______iptr  
       int *iptr; represent   |0xff03|----> int 
                              --------
                              _______fptr
       float *fptr; represent |0xfff8|----> float
                              --------
    Is my illustration for 2 pointer variables above
    is right? Please correct me if I am wrong.

    DV007

  8. #8
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Originally posted by dv007


    Since base on C books,both above pointer variables
    hold non-legal addresses. But actually it outputs
    perfect address for both. Each pointer hold a
    different perfect 32-bit address on my PC. So why C called them "illegal" addresspointers?

    DV007
    because they're someone else's address space. your program doesnt have the rights to use that space. just imagine what things would be like if anything was allowed to write anywhere in ram and there were no controls on who's ram is whos. you wouldnt be able to run a program safely because other programs would always be overwriting it's data.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Ok, start with

    int *pt; /* pt is uninitialised and invalid */

    What this means is that you cannot do something like
    *pt = 42;
    until you've initialised the pointer.
    You don't know where this is pointing, so it's down to chance as to wether this would work or crash. Even if it happens to work, the program is still wrong.


    int *pt = NULL; /* pt is initialised, but invalid */

    A NULL pointer is a place where you can never store a value (or read a value). If you tried
    *pt = 42;
    you would be guaranteed to get a segmentation fault (in some environments at least).


    int a;
    int *pt = &a; /* pt is initialised, and valid */
    In this case, doing
    *pt = 42;
    is a perfectly valid thing to do


    > int *iptr; /* these are non-initialized pointer
    > float *fptr; /* variables and I guess non-legal*/
    > printf("address of iptr is: %p ", iptr);
    > printf("address of fptr is: %p", fptr);
    You can print any pointer you like using this code, since this is not a test of the validity of a pointer.
    The validity of a pointer is determined by whether you can dereference it or not (see above)
    In this case, the pointer is uninitialised, so doing
    *iptr = 42;
    is wrong.

  10. #10
    Sayeh
    Guest
    Adding a little to Salem's work,

    [code]
    int *iptr; /* these are non-initialized pointer
    float *fptr; /* variables and I guess non-legal*/

    printf("address of iptr is: %p ", iptr);
    printf("address of fptr is: %p", fptr);
    [code]

    The question is: Just where _exactly_ does 'iptr' and 'fptr' point to? Make sure you are not confusing the address of where the variable resides in memory with the contents of the pointer.

    'iptr' sits at a specific location in RAM, decided by relative positioning by your compiler and resolved at execution by your link loader.

    For example, let's say that 'iptr' and 'fptr' reside _at_ consecutive memory locations:

    Code:
    Address                RAM
    ------------------------------------------------------------
    0x004A72E1     FF 03 FF F8 A5 71 24 EE
    0x004A72E9     F1 23 A7 EE 64 51 29 20
    ...
    In the above case, 'iptr' is located at 0x004A72E1. This is the value of iptr (it's ADDRESS) aka where it lives in RAM. If I go indirectly through that address = 'a = *iptr', where 'a' is an int, it will make the contents of a equal to 'FF 03'. This is a negative number.

    So when the program starts up, if you have not _initialized_ your variable 'iptr' and 'fptr' to something else (like zero), it will contain whatever value happens to be in RAM at the time.

    RAM is not all zeroes.

    If program 'A' quits and then your program 'B' executes and is thereby loaded into the memory that program 'A' was previously in, the O/S and the memory manager DON'T clean RAM up. Why would they? It's up to you to zero and clean and maintain space you intend to use.

    So, if program 'A' left the Value 0xFF03 at location 0x004A72E1, and your program happens to have variable 'iptr' loaded at that address, its value is going to be 0xFF03 until _you_ specifically set it to something else.

    That is _specifically_ why I initialize every pointer I create to zero (NULL) prior to its use. When I deallocate dynamic allocations, I reset their pointers to zero. That way, I can always tell if I'm using a valid pointer by check it against a known state.

    Everytime I go to use a pointer, the first thing I do is check to see if it's valid.

    Code:
    ...
    if(!myPtr)                                /* ptr has been allocated? */
       return(errCODE);                /* nope, bail */
    ...
    If it's non-zero, I have a very good bet that it's a valid pointer. The only other possibility is that some poorly behaved program has rampaged through my RAM and corruped a nil pointer such that it contains something other than NULL.

  11. #11
    Sayeh
    Guest
    Sorry, I screwed the tags up on the previous. This should be easier to read.

    Code:
    int *iptr; /* these are non-initialized pointer 
    float *fptr; /* variables and I guess non-legal*/ 
    
    printf("address of iptr is: %p ", iptr); 
    printf("address of fptr is: %p", fptr);
    The question is: Just where _exactly_ does 'iptr' and 'fptr' point to? Make sure you are not confusing the address of where the variable resides in memory with the contents of the pointer.

    'iptr' sits at a specific location in RAM, decided by relative positioning by your compiler and resolved at execution by your link loader.

    For example, let's say that 'iptr' and 'fptr' reside _at_ consecutive memory locations:

    Code:
    Address                RAM
    ------------------------------------------------------------
    0x004A72E1     FF 03 FF F8 A5 71 24 EE
    0x004A72E9     F1 23 A7 EE 64 51 29 20
    ...
    In the above case, 'iptr' is located at 0x004A72E1. This is the value of iptr (it's ADDRESS) aka where it lives in RAM. If I go indirectly through that address = 'a = *iptr', where 'a' is an int, it will make the contents of a equal to 'FF 03'. This is a negative number.

    So when the program starts up, if you have not _initialized_ your variable 'iptr' and 'fptr' to something else (like zero), it will contain whatever value happens to be in RAM at the time.

    RAM is not all zeroes.

    If program 'A' quits and then your program 'B' executes and is thereby loaded into the memory that program 'A' was previously in, the O/S and the memory manager DON'T clean RAM up. Why would they? It's up to you to zero and clean and maintain space you intend to use.

    So, if program 'A' left the Value 0xFF03 at location 0x004A72E1, and your program happens to have variable 'iptr' loaded at that address, its value is going to be 0xFF03 until _you_ specifically set it to something else.

    That is _specifically_ why I initialize every pointer I create to zero (NULL) prior to its use. When I deallocate dynamic allocations, I reset their pointers to zero. That way, I can always tell if I'm using a valid pointer by check it against a known state.

    Everytime I go to use a pointer, the first thing I do is check to see if it's valid.

    Code:
    ...
    if(!myPtr)                                /* ptr has been allocated? */
       return(errCODE);                /* nope, bail */
    ...
    If it's non-zero, I have a very good bet that it's a valid pointer. The only other possibility is that some poorly behaved program has rampaged through my RAM and corruped a nil pointer such that it contains something other than NULL.

  12. #12
    Registered User
    Join Date
    May 2002
    Posts
    85
    Thank you very much for relieving my pointer headache. You guys really C experts. Hope to discuss with you guys again in the future.
    Muncho gracias!
    DV007

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Quick Pointer Question
    By gwarf420 in forum C Programming
    Replies: 15
    Last Post: 06-01-2008, 03:47 PM
  2. Replies: 1
    Last Post: 03-24-2008, 10:16 AM
  3. Parameter passing with pointer to pointer
    By notsure in forum C++ Programming
    Replies: 15
    Last Post: 08-12-2006, 07:12 AM
  4. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  5. How did you master pointers?
    By Afrinux in forum C Programming
    Replies: 15
    Last Post: 01-17-2006, 08:23 PM