Stray or Dangling Pointers in C++
By: Kamini in C++ Tutorials on 2007-09-14
Stray or Dangling Pointers
One source of bugs that are nasty and difficult to find is stray pointers. A stray pointer is created when you call delete on a pointer--thereby freeing the memory that it points to--and later try to use that pointer again without reassigning it.
It is as though the Acme Mail Order company moved away, and you still pressed the programmed button on your phone. It is possible that nothing terrible happens--a telephone rings in a deserted warehouse. Perhaps the telephone number has been reassigned to a munitions factory, and your call detonates an explosive and blows up your whole city!
In short, be careful not to use a pointer after you have called delete on it. The pointer still points to the old area of memory, but the compiler is free to put other data there; using the pointer can cause your program to crash. Worse, your program might proceed merrily on its way and crash several minutes later. This is called a time bomb, and it is no fun. To be safe, after you delete a pointer, set it to null (0). This disarms the pointer.
NOTE: Stray pointers are often called wild pointers or dangling pointers.
Program below illustrates creating a stray pointer.
WARNING: This program intentionally creates a stray pointer. Do NOT run this program--it will crash, if you are lucky.
1: // 2: // Demonstrates a stray pointer 3: typedef unsigned short int USHORT; 4: #include <iostream.h> 5: 6: int main() 7: { 8: USHORT * pInt = new USHORT; 9: *pInt = 10; 10: cout << "*pInt: " << *pInt << endl; 11: delete pInt; 12: pInt = 0; 13: long * pLong = new long; 14: *pLong = 90000; 15: cout << "*pLong: " << *pLong << endl; 16: 17: *pInt = 20; // uh oh, this was deleted! 18: 19: cout << "*pInt: " << *pInt << endl; 20: cout << "*pLong: " << *pLong << endl; 21: delete pLong; 22: return 0; 23: } Output: *pInt: 10 *pLong: 90000 *pInt: 20 *pLong: 65556 Null pointer assignment
(Your output may look different.)
Analysis: Line 8 declares pInt
to be a pointer to USHORT, and pInt is pointed to newly
allocated memory. Line 9 puts the value 10 in that memory, and line 10
prints its value. After the value is printed, delete is called on the
pointer. pInt is now a stray, or dangling, pointer.
Line 13 declares a new pointer, pLong, which is pointed at the memory
allocated by new.
Line 14 assigns the value 90000 to pLong, and line 15 prints
its value.
Line 17 assigns the value 20 to the memory that pInt points to, but pInt no longer points anywhere that is valid. The memory that pInt points to was freed by the call to delete, so assigning a value to that memory is certain disaster.
Line 19 prints the value at pInt. Sure enough, it is 20.
Line 20 prints 20, the value at pLong; it has suddenly been
changed to 65556. Two questions arise:
1. How could pLong's value change, given that pLong
wasn't touched?
2. Where did the 20 go when pInt was used in line 17?
As you might guess, these are related questions. When a value was placed at pInt
in line 17, the compiler happily placed the value 20 at the memory
location that pInt previously pointed to. However, because that memory
was freed in line 11, the compiler was free to reassign it. When pLong
was created in line 13, it was given pInt's old memory location. (On
some computers this may not happen, depending on where in memory these values
are stored.) When the value 20 was assigned to the location that pInt
previously pointed to, it wrote over the value pointed to by pLong.
This is called "stomping on a pointer." It is often the unfortunate
outcome of using a stray pointer.
This is a particularly nasty bug, because the value that changed wasn't
associated with the stray pointer. The change to the value at pLong was
a side effect of the misuse of pInt. In a large program, this would be
very difficult to track down.
Just for fun, here are the details of how 65,556 got into that memory address:
- 1. pInt was pointed at a particular memory location, and
the value 10 was assigned.
2. delete was called on pInt, which told the compiler that it could put something else at that location. Then pLong was assigned the same memory location.
3. The value 90000 was assigned to *pLong. The particular computer used in this example stored the four-byte value of 90,000 (00 01 5F 90) in byte-swapped order. Therefore, it was stored as 5F 90 00 01.
4. pInt was assigned the value 20--or 00 14 in hexadecimal notation. Because pInt still pointed to the same address, the first two bytes of pLong were overwritten, leaving 00 14 00 01.
5. The value at pLong was printed, reversing the bytes back to their correct order of 00 01 00 14, which was translated into the DOS value of 65556.
DO use new to create objects on the free store. DO use delete to destroy objects on the free store and to return their memory. DON'T forget to balance all new statements with a delete statement. DON'T forget to assign null (0) to all pointers that you call delete on. DO check the value returned by new.
Add Comment
This policy contains information about your privacy. By posting, you are declaring that you understand this policy:
- Your name, rating, website address, town, country, state and comment will be publicly displayed if entered.
- Aside from the data entered into these form fields, other stored data about your comment will include:
- Your IP address (not displayed)
- The time/date of your submission (displayed)
- Your email address will not be shared. It is collected for only two reasons:
- Administrative purposes, should a need to contact you arise.
- To inform you of new comments, should you subscribe to receive notifications.
- A cookie may be set on your computer. This is used to remember your inputs. It will expire by itself.
This policy is subject to change at any time and without notice.
These terms and conditions contain rules about posting comments. By submitting a comment, you are declaring that you agree with these rules:
- Although the administrator will attempt to moderate comments, it is impossible for every comment to have been moderated at any given time.
- You acknowledge that all comments express the views and opinions of the original author and not those of the administrator.
- You agree not to post any material which is knowingly false, obscene, hateful, threatening, harassing or invasive of a person's privacy.
- The administrator has the right to edit, move or remove any comment for any reason and without notice.
Failure to comply with these rules may result in being banned from submitting further comments.
These terms and conditions are subject to change at any time and without notice.
- Data Science
- Android
- React Native
- AJAX
- ASP.net
- C
- C++
- C#
- Cocoa
- Cloud Computing
- HTML5
- Java
- Javascript
- JSF
- JSP
- J2ME
- Java Beans
- EJB
- JDBC
- Linux
- Mac OS X
- iPhone
- MySQL
- Office 365
- Perl
- PHP
- Python
- Ruby
- VB.net
- Hibernate
- Struts
- SAP
- Trends
- Tech Reviews
- WebServices
- XML
- Certification
- Interview
categories
Related Tutorials
Calculating total based on the given quantity and price in C++
Sorting an array of Strings in C++
Matrix using nested for loops in C++
Compute the square root of the sum of the squares of an array in C++
Calculate average using Two-Dimensional Array in C++
Two-Dimensional Array Manipulation in C++
Compiling and Linking Multiple Source Files in C++
Escape Sequences for Nonprintable Characters in C++
Using the Built-in Arithmetic Types in C++
Comments