Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Question about pointers in C/C++

  1. Nov 20, 2008 #1
    Isn't a pointer simply a memory address? Then why is the following illegal?

    int x = 1;
    char *p = &x;

    &x should simply evaluate to an address in memory and that should be stored in the content of p. If this was run on a 32-bit architecture, under ASCII formatting, then

    *p = 'a';

    Will modify the memory unit at address &x and what would happen is that the first 8 bits of x would be modified to the bit character representation of 'a' effectively changing the value of x.

    What is wrong with this reasoning?
     
    Last edited: Nov 20, 2008
  2. jcsd
  3. Nov 20, 2008 #2

    mgb_phys

    User Avatar
    Science Advisor
    Homework Helper

    Who says it's illegal? That's perfectly reasonable c.

    It works with a single byte value in the lowest byte of the int, but it migth not give you the result you expect if you move p, especialy on a machine with little endian byte order.
     
  4. Nov 20, 2008 #3

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    First off, it's not legal C. You have to do an explicit cast if you want to reinterpret a pointer to one type as a pointer to another type. e.g.

    char *p = (char*) &x;

    Secondly, it's non-portable C; the language gives you very few guarantees about the memory layout of any type. While the most common effects of

    *p = 'a'

    are either to modify the least significant 8 bits or the most significant 8 bits of x as if it were stored in 2's complement notation... that is by no means a certainty. Other reasonable things that might happen are the bits change as if x is stored in 1's complement notation, or that your program soon triggers an access violation because you overwrote some 'trap' bits in the integer representation of x. And that doesn't even begin to cover the truly bizzare things that could happen!



    There is almost never any reason to resort to such arcane tactics. Whenever you're tempted to do so, you should stop and take a moment to look for a more reasonable way to do what you want to do. If you decide there isn't one... then stop again and think really hard about it. If you've convinced yourself that's really what you want to do... then stop once more and really, really make sure. Only then should you do such a thing, and even then only after reconsidering it one more time.
     
  5. Nov 20, 2008 #4

    zyh

    User Avatar

    [​IMG]
    I draw a picture to explain you question.
    Like Hurkyl said.
    In a 32 bit intel CPU (which is little endian see:http://en.wikipedia.org/wiki/Little_endian)
    the pointer p which is defined " char *p " is a pointer each ONE BYTE memory.
    But an int variable occupy Four Bytes.

    So, if you use the statement: char *p = &x; the left side and right doesn't have the same pointer type. So a implicit type convert generated by compiler.

    Once you use the statement :*p = 'a'. Only one Byte in (Yellow color in my image) will be change to 'a'.
     

    Attached Files:

  6. Nov 21, 2008 #5
    I am totally sure I have understood what you are saying zyh. You went over that point "the pointer p which is defined " char *p " is a pointer each ONE BYTE memory." too quickly. Do you mean that an int pointer points to 4 bytes, whereas a char pointer points to only 1?

    If so, I'm at loss because my understanding was that &x is a single address in memory (of the first of the 4 bytes allocated to x) and through a symbolic table indicating to the compiler that x is an int type variable, the compiler 'knows' it needs to write on that address and the 3 following when changing the value of x.

    What loses me is that I don't understand why, say x is an int and ch a char, &ch and &x are fundamentally different. According to my schema, they both evaluate to memory addresses, don't they?
     
  7. Nov 21, 2008 #6

    mgb_phys

    User Avatar
    Science Advisor
    Homework Helper

    The pointers are the same as far as the processor is concerned, the compiler has to keep track of the differences.
    Yes
    Yes - thats the problem with c. You could reserve some memory for a single char and then through a pointer write a 4byte int starting at that address. the compiler will happily overwrite any data/program memory after the char.
     
    Last edited: Nov 22, 2008
  8. Nov 21, 2008 #7
    So is it only through information that the compiler keeps in the symbolic table that it is capable to distinguish between pointers and enforce assignment rules? In that case, does this mean we can't operate with pointers that don't originate from declared variables, i.e. in the same way int x = 3; is different from int y = 3, x = y;, because then the compiler has no means to enforce rules?
     
  9. Nov 22, 2008 #8

    mgb_phys

    User Avatar
    Science Advisor
    Homework Helper

    You can do pretty much anythign you want with pointers.
    There is nothing to stop you doing
    char p; memset(*p,0,1024);
    which will overwrite the next k of memory.

    The compiler does it's best to protect you by forcing you to cast the wrong type of pointer.
    int x = 1; char *p = &x; //The compiler will warn you (or give an error on some compilers)
    int x = 1; char *p = (char*)&x; //Tells the compiler you think you know what you are doing.
    Generally at run time the OS doesn't know what the pointer points at.
    void *p explicitly says you don't care what it is going to point at - so you can write a function that can work with different types.
     
  10. Nov 22, 2008 #9
    I see. Now, there aren't really any 'type' of pointers, it's all about the compiler checking the statements involving pointers against their original declaration, right? Do we only think of them in this way so that we can predict how the compiler will react?

    But then again there aren't really any types since it's all 1's and 0's in the end, the compiler is responsible to 'fake' the difference.
     
  11. Nov 22, 2008 #10

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    No, we think about it this way because its simpler, harder to make mistakes, and gives the compiler opportunities for optimization that it wouldn't otherwise have.
     
  12. Nov 23, 2008 #11
    Or to put it another way: &ch and &x are not fundamentally different. It is just that the compiler pretends they are different, as a safety feature. This is because even though the compiler knows how to interchange char * and int * as if they were the same type, it is almost always a bad idea to do this (for the reasons described by Hurkyl and others). When you cast a char * to an int * you are not actually changing its value, you are just circumventing the safety feature.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?



Similar Discussions: Question about pointers in C/C++
  1. Questions about C (Replies: 7)

Loading...