Thread: Create a null pointer after using a delete

  1. #1
    Registered User
    Join Date
    Jul 2014
    Location
    Central Arizona
    Posts
    61

    Create a null pointer after using a delete

    In jumping into C++ it says something like this: It's not necessary but when you delete a pointer it's a good idea to reset it as a null pointer. That if your code try's to dereference the pointer after being freed, your program will crash. This happens to a lot of experienced programmers This could corrupt users data.
    delete p_int;
    p_int = NULL;

    This raises a lot of questions for me as a beginners.

    1. If you can deference a pointer after the memory is freed, why can't you just delete the pointer?

    2. If you can do 1, how do you delete the pointer using code?

    3. Every thing I've read says that free memory is handed out in a sequenced order. I don't believe that is true at all. I may be wrong. Why can't you put the data in any number of places if it will fit. Isn't the compiler smart enough to know where bytes (bits)and pieces are stored?

    4. If you storing anything in free memory must use a pointer to it?

    5. Can a pointer or something similar be used with stack memory?




    Last edited by papagym177; 08-07-2014 at 05:12 PM.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    1) A pointer is a variable stored on the stack. Variables on the stack cannot be deleted. They are freed automatically at the end of the scope it is in. There is no way in the language to prematurely delete a variable on the stack. Since you must use a pointer to objects stored on the heap, it follows that you cannot delete the pointer that points to what you allocate, but you can delete what the pointer points to.

    2) Since you cannot do 1, this makes no sense. You cannot delete a pointer (unless that pointer is stored on the heap).

    3) This is not true. How memory is allocated on the heap is implementation defined, which means the compiler and the OS are responsible for it. The language doesn't care or know. Some operating systems may use some sequenced list. Some may not. Modern operating systems such as Windows, Linux and OS certainly do not use sequenced lists. It allocates memory where it is available, i.e. it is smart enough to know where more memory can be allocated.

    4) Yes, you need a pointer to it.

    5) Yes, a pointer is just a variable that contains memory addresses and since the stack is located in memory, you can point a pointer to a stack variable.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by papagym177 View Post
    In jumping into C++ it says something like this: It's not necessary but when you delete a pointer it's a good idea to reset it as a null pointer. That if your code try's to dereference the pointer after being freed, your program will crash. This happens to a lot of experienced programmers This could corrupt users data.
    delete p_int;
    p_int = NULL;

    This raises a lot of questions for me as a beginners.

    1. If you can deference a pointer after the memory is freed, why can't you just delete the pointer?

    2. If you can do 1, how do you delete the pointer using code?

    3. Every thing I've read says that free memory is handed out in a sequenced order. I don't believe that is true at all. I may be wrong. Why can't you put the data in any number of places if it will fit. Isn't the compiler smart enough to know where bytes (bits)and pieces are stored?

    4. If you storing anything in free memory must use a pointer to it?

    5. Can a pointer or something similar be used with stack memory?
    1) "Deleting" a pointer causes it's destructor to be called (if any) and then relinquishes ownership of that chunk of memory back to the system to be used elsewhere. So the pointer itself is still going to contain that memory address. If you then try to dereference the pointer things may seem to work normally for a while or the program may well crash at any point. Setting it to NULL ensures that an error will be raised the moment you try to dereference the invalid pointer.

    2) Just as you have it: "delete p_int;". For an array you would use the "delete[] p_int;".

    3) No, the implementation is free to dole it out however it likes.

    4) It sounds like you're asking if an allocated chunk should have at least one pointer attached to it? If so, yes, because otherwise you'd have a memory leak.

    5) Absolutely! Just don't "delete" something that hasn't been allocated with "new".

    Oh, and once you understand how pointers work, be sure to study up on the principles of RAII...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    Registered User
    Join Date
    Jul 2014
    Location
    Central Arizona
    Posts
    61
    Elysia, you've done it again. Thanks for helping me get things straight in my head, your a great help.

    I have a couple of more questions on pointer. Is it possible to have more than one pointer point to the same place in memory? Is this ever done??

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by papagym177 View Post
    I have a couple of more questions on pointer. Is it possible to have more than one pointer point to the same place in memory? Is this ever done??
    Yes, it is possible, and it is very common. When sharing data between data structures, it is common to have a pointer to the shared portion. This saves memory since the information does not need to be duplicated. Furthermore, any changes to the shared portion will be reflected in every data structure that contains a pointer to that shared portion. This is one common way where multiple pointers to the same place in memory is used. This pattern is so common that there is a special type of "smart pointer" called shared_ptr that exists for exactly this purpose, to ensure that the common portion of memory is only freed once the last data structure that has a pointer to the data is destroyed, the shared data structure is also freed.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by papagym177 View Post
    I have a couple of more questions on pointer. Is it possible to have more than one pointer point to the same place in memory? Is this ever done??
    This is very common, for instance to iterate through a linked list (or some other structure) allocated on the heap. You might do something like:

    Code:
    for( list* i = head; i != nullptr; i = i->nextElement )
    This is just one example, but you can see that both i and head point to the same memory at the start.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Sebastiani View Post
    Setting it to NULL ensures that an error will be raised the moment you try to dereference the invalid pointer.
    That's not true. Dereferencing a NULL pointer is just as much undefined behaviour as dereferencing a pointer to something that no longer exists as far as the program is concerned. There is certainly no guarantee that dereferencing a NULL will cause an immediate crash.

    In practice, any form of undefined behaviour (dereferencing a NULL, dereferencing a pointer to something that doesn't exist, falling off the end of an array, modifying a variable twice in a single statement, etc etc) can result in intermittent or unpredictable behaviour. And often does.

    The usual reason for setting a pointer to NULL after deleting it is that NULL can be tested for (e.g. "if (pointer != NULL) dereference(pointer);"). It is not to give a guaranteed crash for dereferencing the pointer.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by grumpy View Post
    That's not true. Dereferencing a NULL pointer is just as much undefined behaviour as dereferencing a pointer to something that no longer exists as far as the program is concerned. There is certainly no guarantee that dereferencing a NULL will cause an immediate crash.

    In practice, any form of undefined behaviour (dereferencing a NULL, dereferencing a pointer to something that doesn't exist, falling off the end of an array, modifying a variable twice in a single statement, etc etc) can result in intermittent or unpredictable behaviour. And often does.

    The usual reason for setting a pointer to NULL after deleting it is that NULL can be tested for (e.g. "if (pointer != NULL) dereference(pointer);"). It is not to give a guaranteed crash for dereferencing the pointer.
    Okay, perhaps it isn't well-defined, but AFAIK most systems will behave in such a way, so it is still practically true. Just don't bank on it.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  9. #9
    Registered User
    Join Date
    Jul 2014
    Location
    Central Arizona
    Posts
    61
    Elysia, does a smart pointer or shared pointer have any special syntax that will distinguish it from other pointers? What really happening when you dereference a pointer? Thanks
    Last edited by papagym177; 08-08-2014 at 01:26 PM.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,550
    Quote Originally Posted by papagym177
    does a smart pointer or shared pointer have any special syntax that will distinguish it from other pointers?
    A "shared pointer" is a kind of smart pointer. The difference is firstly one of semantics: a shared pointer is used for the semantics of shared ownership, whereas no such semantics would be associated with an ordinary pointer except as established in the code (e.g., to implement a shared pointer). Related to this is the difference of type: a standard shared pointer to an int would be of type std::shared_ptr<int> whereas a pointer to an int would be of type int*. Since a shared_ptr is an object of class type, it can (and does) have member functions that are "special syntax that will distinguish it from other pointers", but this "special syntax" is related to the semantics of shared ownership. Otherwise, the idea is for shared_ptr to have the same pointer syntax as ordinary pointers.

    Quote Originally Posted by papagym177
    What really happening when you reference a pointer?
    I presume that by "reference" you mean "dereference", in which case: it results in what the pointer points to. Beyond this, it depends on the code, compiler, compiler options, etc.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Sebastiani View Post
    Okay, perhaps it isn't well-defined, but AFAIK most systems will behave in such a way, so it is still practically true. Just don't bank on it.
    There is certainly a perception that a crash is the most common symptom of pointer molestation, simply because it is most blatant. And an immediate crash is often viewed as being more common than others, simply because it is easier to induce and easier to track down.

    In practice, although I haven't collected formal statistics, I would suggest the most common symptom is not a crash it all: it is silent data corruption or poisoning. However, such symptoms aren't visible immediately and aren't necessarily easy to induce repeatably, so developers default to believing they are rare. A deferred crash (data gets corrupted, that data is used by some unrelated code as a pointer or array dimension/index, some other data gets corrupted <repeat a few times>, leading to an eventual crash at some point in code unrelated to the original problem) is at least as common as an immediate crash too.

    That's why I advocate techniques to prevent such problems, rather than (the more common approach by most developers) trying to find them after the fact.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  12. #12
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    There is certainly no guarantee that dereferencing a NULL will cause an immediate crash.
    it is silent data corruption or poisoning.
    O_o

    I'd say that neither is most common.

    You don't need to collect individual statistics; you just need to read the manual for most common platforms for which statistics already exist.

    Certainly, you don't see an immediate crash or get any sort of data corruption on many of the most common platforms; you are offered the opportunity, somehow, to recover from the error. For an example using most modern operating systems running on "x86" flavors: the memory access fails at the processor level thanks to memory segmentation/mapping which is then somehow translated and made available to the program. (To be more specific, on "Windows" you see an "SEH" exception raised while on "Linux" you get `SIGSEGV'.) While obviously not all platforms are "x86" flavors, a large number of platforms offer similar features essentially trapping a derefernce of, whatever it may actually be, null. (Yes, we can include embedded systems where dereferncing null is often the same as illegal instructions which in turn can be trapped.) Oddly, none of this changes the simple fact that dereferencing null is undefined within the C/C++ standards.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by phantomotap View Post
    For an example using most modern operating systems running on "x86" flavors: the memory access fails at the processor level thanks to memory segmentation/mapping which is then somehow translated and made available to the program.
    Even if we limit ourselves to x86, the behaviour of the platform (what you've described as "at the processor level" is really the MMU - memory management unit - of modern processors) is shielded from programs by modern operating systems. While you're right that failures "at the processor level" are propagated back to your program (assuming they don't trigger BSOD under windows, unix kernel panics, or similar) a lot of invalid accesses are detected by the OS itself (or by device drivers). That's part of the design in modern multitasking operating systems to prevent one process accessing memory owned by another - and means, among other things, that the memory accessed via a NULL pointer is often unique to a process rather than something that causes the MMU itself to signal an invalid access.

    The thing is, different operating systems (and device drivers) have different strategies for how they detect invalid memory accesses, and not all of those strategies directly involve the MMU - which is what triggers those failures you describe as "at the processor level". A consequence of that is that the behaviour on dereferencing NULL (or any other pointer where, according to the C++ standard, the result is undefined) is not set in stone, even for one operating system, let alone when comparing operating systems, or hardware platforms. Which, I assume, is one reason the standard leaves such things undefined, rather than requiring a particular pattern of detection or recovery.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  14. #14
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Even if we limit ourselves [...] of detection or recovery.
    O_o

    I'm clearly combing hardware and operating system with the "platform" vocabulary as most any reading of the example offers not referring specifically to the MMU component as you claim. The distinctions you are trying to make are thus tedious in context, and the comments offered in response to claims never made are irrelevant. Furthermore, some of your claims are misleading; for example, a modern "x86" operating system never mapping anything in the null pointer range (You can make a few configuration changes to the older "Linux" kernel and rebuild allowing you to use the mapped null pointer as a valid address within an application if you really wanted.) as valid for a given application is exactly why the processor does indeed signal an invalid access for the null pointer so the operating system can notify the application.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Does static initialization of pointer make it null pointer
    By Saurabh Mehta in forum C Programming
    Replies: 1
    Last Post: 11-23-2012, 12:05 AM
  2. delete NULL;
    By Just in forum C++ Programming
    Replies: 10
    Last Post: 11-25-2004, 07:07 PM
  3. delete on a NULL pointer
    By myname in forum C++ Programming
    Replies: 18
    Last Post: 10-03-2003, 08:23 PM
  4. Which comes first...delete [] or NULL?
    By Waldo2k2 in forum C++ Programming
    Replies: 13
    Last Post: 08-09-2002, 09:05 AM