Dereferencing pointers without pointing them at a variable

前端 未结 4 1279
野趣味
野趣味 2020-12-02 01:14

I\'m having trouble understanding how some pointers work. I always thought that when you created a pointer variable (p), you couldn\'t deference and assign (*p = value) unle

相关标签:
4条回答
  • 2020-12-02 01:48

    Not to seem like a "Me too!" answer, but the other answers don't answer your core question:

    Okay I get that the first one shouldn't work either, but why does it. That's what I'm after.

    In this case, you are invoking Undefined Behavior. Both the C and C++ standards are clear that when a variable is uninitialized, its contents are undefined. And when it says undefined, it means, unknown. These pointers could contain literally anything. Because they're uninitialized, they contain whatever memory happened to be at the location that the compiler chose for those two variables.

    In this case, your first variable just happens to contain a pointer that points within your program's memory space. The second just happens to contain a pointer that points outside your program's memory space. It could be anything from a null pointer to a pointer to your main function. Whatever it is, it's irrelevant: You don't need to know or care, because it's garbage. You're expected to write over it anyway.

    It's a common expression among C programmers that invoking undefined behavior causes demons to fly from your nose. This is because the C standard states quite clearly that when behavior is not defined, the compiler is free to do anything it wants to do. And that includes launching nuclear missiles, resetting your bank account to zero, or, yes, causing winged creatures to flitter forth from your nasal cavity.

    0 讨论(0)
  • 2020-12-02 01:50

    I always thought that when you created a pointer variable (p), you couldn't deference and assign (*p = value) unless you either malloc'd space for it (p = malloc(x)), or set it to the address of another variable (*p = &a)

    For practical purposes you thought right. Better keep thinkig that.

    If you do what in in your example the behavior of the program is undefined. What means anything can happen, including a misleading "works" feeling. But it is nothing but recipe for disaster.

    0 讨论(0)
  • 2020-12-02 02:06
    // This works
    int* colin;
    *colin = 5;
    

    Welcome to undefined behavior: the fact that it does not crash does not mean that it works. Accessing uninitialized pointer is always wrong, yet sometimes it does not crash.

    couldn't deference and assign unless you either malloc'd space for it or set it to the address of another variable

    This is correct. In general, you need to point your pointer to some place that has been allocated to your program. There are multiple ways of doing that, but they all boil down to one of the two scenarios that you describe - the pointer is pointed either to a dynamically allocated memory (i.e. malloc), or to statically allocated memory (i.e. a variable).

    0 讨论(0)
  • 2020-12-02 02:06

    I always thought that when you created a pointer variable (p), you couldn't deference and assign (*p = value) unless you either malloc'd space for it (p = malloc(x)), or set it to the address of another variable (*p = &a)

    There are things in C that are disallowed, so the C compiler will issue an error and refuse to compile the program, and there are other things for which the C standard does not define any behavior, so there are no constraints on what an implementation may do ... the reason for this is to give implementations great latitude in how they are implemented and to allow them to produce very fast code. This differs from more modern languages that put a greater value on protecting programmers from their own errors. As a consequence there's a greater burden on the programmer to write valid code.

    Your code is an example where the behavior is undefined. The compiler does not generate checks to see whether the value of p is valid when you dereference and assign it ... it may contain junk and the store may be to an arbitrary location in memory, or it may point to inaccessible memory and the store will crash (there are other possibilities since the behavior is undefined, but these are the ones that will occur in common real-world implementations). That your code crashed on one store but not the other is pure happenstance, an artifact of the fine details of the implementation ... a different compiler, a different version of the compiler, a slight change to your source ... any of these things and others could change the results by changing the value that happened to be in p ... some arbitrary value left on the stack, because p is a stack variable (The C language standard does not mandate or even mention a stack, but common real-world implementations allocate auto variables on the stack.)

    The bottom line is that your program is, as you know, wrong, even though it was "allowed". As R. Martinho Fernandes said in the comments, you're unlucky that the first store "worked" ... in a commercial product, having something like that "work" would be extremely unfortunate because it can fail at any time, including the worst possible circumstances. The C language does not help you here ... you need to be very disciplined.

    0 讨论(0)
提交回复
热议问题