Thread: [Dev-C++] Deliberate crashes - more information
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: Bob W. <bo...@ph...> - 2002-04-08 21:44:13
|
Ladies and gentlemen: Earlier I posted an lengthy "treatise" on problems related to quote from = Sams Teach Yourself C++ in 24 Hours, third Edition by Jesse Liberty. = Since that posting I have exchanged several lengthy emails with the = author concerning what I perceived as a problem with the wording of his = warning. During the corse of the day, I believe we have come to an = understanding. Mr. Liberty has asked that I inform the readers of the = Dev-C++ User Mailing List of the results of this discussion. He was = concerned that my comments would make people think that he had "got this = wrong." To that end, I am forwarding the entire thread of our = correspondance in reverse cronological order.=20 -------------------------------------------------------------------------= ------- -------------------------------------------------------------------------= ------- No problem. -------------------------------------------------------------------------= ------- -------------------------------------------------------------------------= ------- Okay, I'll work on it. Thanks for the feedback! -j ------------------------------- Jesse Liberty Liberty Associates, Inc. .NET Training & Development http://www.LibertyAssociates.com=20 -------------------------------------------------------------------------= ------- -------------------------------------------------------------------------= ------- Jesse, I don't think this substantially changes the meaning of the chapter, = but you are of course free to disagree. Neither do I, but I would suggest that: Calling delete on that pointer again may crash your program! is neither as strong a warning nor as precise as what I suggested. By = simply inserting "may," you might be weakening the warning to the point = that the uninitiated (or, if you prefer, the great unwashed masses = uncleansed by the purity of C++) would not consider it grevious error to = not set used pointers to null.=20 Regards, Bob -------------------------------------------------------------------------= ------- -------------------------------------------------------------------------= ------- Bob, Yes, of course, the book should have made the sentence more precise, and = I'll fix that. The example you quoted in your original post, however, = was not on point: it showed the reuse of a deleted pointer, and that of = course will crash. I thought at the time you were complaining that = marking the pointer to null did not protect you from that crash (which I = never said it would). It turns out, apparently that you were actually = complaining that the non-nulled deleted pointer did not crash as I said = it would >> How could someone who is expert enough to write a beginning book on = C++ make such an error=20 Seems like a bit of overstatement to me, but I will in the next edition = qualify the sentence to=20 Calling delete on that pointer again may crash your program! I don't think this substantially changes the meaning of the chapter, but = you are of course free to disagree. Thanks. -j ------------------------------- Jesse Liberty Liberty Associates, Inc. .NET Training & Development http://www.LibertyAssociates.com=20 -------------------------------------------------------------------------= ------- -------------------------------------------------------------------------= ------- Jesse, Yes. It will crash the program. Sooner or later. If you call delete on = a pointer and you do not set it to null, it is pointing to random = memory. That may work for a while, but it certainly will crash sooner or = later. The only safe alternative is declare it null. =20 A simple declarative sentence that purports to state a universal fact = without any clauses that restrict or modify the universality of that = fact must be assumed to apply to all situations. In making a simple = declarative statement without any sort of limiting modifiers, you state = that all programs will crash. They do not. Your quote appears on page = 147. Directly below the quote is an example program which will not crash = if you delete a deleted pointer. In the simplest employment of = Aristotelian logic, if you show that something contradicts itself, you = have shown that the thing is untrue. I have done that, therefore your = statement is incorrect, invalid, or not true. Like it or not, you made = an error when you wrote the warning. Using an exclamation point to end = the sentence under discussion only strengthens my criticism.=20 That said, I concur that a dangling pointer is like a smoldering ember = in a room full of gasoline and gunpowder. Further I agree that only a = fool or a very inexperienced or careless programmer fails to both return = memory to the heap and set pointers to null after they have been used.=20 You have a few things confused here: 1. Delete a pointer and do not null it. Then call delete again. It CAN = crash immediately, and will crash sooner or later. I go back to what I said before. Your quote from the book is a absolute. = It is not a conditional statement as "It CAN crash immediately" above = is. Simply put, the book should have had been more accurate. Your entire = sentence above, "It CAN crash immediately, and will crash sooner or = later", suffers from the same problem. You and I can both write a simple = program that deletes a deleted pointer and the program will not crash = but run through to its normal termination. Such a contradiction makes = the sentence above and in the book inaccurate. The boxed warning on page = 147, should have read:=20 When you call delete on a pointer, the memory it points to is freed. = Calling delete on that pointer again may not cause a program to crash = immediately, and a simple program like the one in listing 9.4 below may = not crash at all, but more complex, longer running programs will = ultimately crash.=20 If your warning had been worded in that fashion, it would have been 100% = accurate, and we would not be having this discussion. 2. Delete a pointer and use it again (e.g., assign a value to it). = That will crash, sooner or later Agreed , but the criticism and comments discussed above apply to this = absolute statement as well.=20 3. Delete a pointer and assign null. Then delete again. That is safe, = as I said in the book Agreed.=20 4. Delete a pointer and assign null and then reuse it. Should crash = right away Agreed.=20 Your example in your email was of #4, and it crashes just as it said. = The book was not wrong. I'm sorry I wasn't clearer, but the book was = correct. This may be a very nit-picky argument that deals with both the syntax = and grammar of English, but your warning in the book is wrong. Examine = the original statement on page 147, what you have posted to me, and what = I have posted above. Hopefully such an examination will show you why I = am so adamant. If you cannot see the difference, and why I maintain that = the warning in the book is wrong, I will try to give you a better = explanation of why that is so.=20 Please post a correction to the dev-c mailing list you originally = posted the criticism on. I will be happy to oblige once the issue is settled.=20 -------------------------------------------------------------------------= ------- -------------------------------------------------------------------------= ------- Bob, I am sorry as well. What you said, and I quote, "When you call delete on = a pointer, the memory it points to is freed. Calling delete on that = pointer again will crash your program!" In point of fact it does not = crash the program. Try it with either the Bloodshed or the VC++ 6.0 = compiler and you will see what I mean. =20 Yes. It will crash the program. Sooner or later. If you call delete on a = pointer and you do not set it to null, it is pointing to random memory. = That may work for a while, but it certainly will crash sooner or later. = The only safe alternative is declare it null. =20 You have a few things confused here: 1. Delete a pointer and do not null it. Then call delete again. It CAN = crash immediately, and will crash sooner or later. 2. Delete a pointer and use it again (e.g., assign a value to it). That = will crash, sooner or later 3. Delete a pointer and assign null. Then delete again. That is safe, as = I said in the book 4. Delete a pointer and assign null and then reuse it. Should crash = right away Your example in your email was of #4, and it crashes just as it said. = The book was not wrong. I'm sorry I wasn't clearer, but the book was = correct. PS: Please do update the mailing list (I don't have the email = address) on which you posted this msg; I'd hate for folks to think I got = this wrong. Please excuse my ignorance, but update what mailing list? Or perhaps = you mean to post a correction. =20 Please post a correction to the dev-c mailing list you originally = posted the criticism on. -------------------------------------------------------------------------= ------- -------------------------------------------------------------------------= ------- I'm sorry but the book is correct. Please examine what I wrote and = compare it to what you did in your test program. I said you can set a pointer to null and then delete it without it = crashing. That is 100% correct. Calling delete on a null pointer is guaranteed to be safe. I am sorry as well. What you said, and I quote, "When you call delete on = a pointer, the memory it points to is freed. Calling delete on that = pointer again will crash your program!" In point of fact it does not = crash the program. Try it with either the Bloodshed or the VC++ 6.0 = compiler and you will see what I mean.=20 I did not say you can then try to use the pointer, or assign a new = value to it. You can not, and I make that explicitly clear in the book.=20 You write: If set pHeap to null, however, and then try to assign *pHeap a value, = as shown below, the program will crash.=20 Right. It will crash, as it should; once set to null you can not then = assign a value to it. All you can safely do is call delete.=20 I agree wholeheartedly, it should crash and it does. However, that was = not my initial criticism. It was an outgrowth of experimentation to see = if the program would crash as similar programs in other languages do if = you try to manipulate a null pointer.=20 As part of my ongoing effort to support my books, I now offer a FAQ, = source code and related materials on my web site: = http://www.LibertyAssociates.com. While you are there, you may want to = sign up for my on-line support discussion center: = http://forums.delphiforums.com/LibertyBooks. I'm happy to discuss this = in detail on the discussion center if there is still any confusion. I will certainly log on to your forms. Thanks for the link.=20 PS: Please do update the mailing list (I don't have the email address) = on which you posted this msg; I'd hate for folks to think I got this = wrong. Please excuse my ignorance, but update what mailing list? Or perhaps you = mean to post a correction.=20 -------------------------------------------------------------------------= ------- -------------------------------------------------------------------------= ------- I'm sorry but the book is correct. Please examine what I wrote and = compare it to what you did in your test program. I said you can set a pointer to null and then delete it without it = crashing. That is 100% correct. Calling delete on a null pointer is guaranteed to be safe. I did not say you can then try to use the pointer, or assign a new value = to it. You can not, and I make that explicitly clear in the book.=20 You write: If set pHeap to null, however, and then try to assign *pHeap a value, as = shown below, the program will crash.=20 Right. It will crash, as it should; once set to null you can not then = assign a value to it. All you can safely do is call delete.=20 In fact elsewhere in the book I point out that this is a feature, it = crashes reliably, as opposed to what happens if you delete memory and do = not assign it to null (in which case, if you use the pointer you = overwrite random memory and it crashes unpredictably). As part of my ongoing effort to support my books, I now offer a FAQ, = source code and related materials on my web site: = http://www.LibertyAssociates.com. While you are there, you may want to = sign up for my on-line support discussion center: = http://forums.delphiforums.com/LibertyBooks. I'm happy to discuss this = in detail on the discussion center if there is still any confusion. Thank you.=20 -j PS: Please do update the mailing list (I don't have the email address) = on which you posted this msg; I'd hate for folks to think I got this = wrong. ------------------------------- Jesse Liberty Liberty Associates, Inc. .NET Training & Development http://www.LibertyAssociates.com=20 -------------------------------------------------------------------------= ------- -------------------------------------------------------------------------= ------- (I forwarded my original message to Mr. Liberty at = jli...@li...) I will appologize in advance for the length of this message. Anyone who = has much experience in programming knows pointers are an extremely = powerful and useful construct, but that they can be the quickest path to = the hellfire and damnation of runtime erros and program crashes if = careful attention is not paid to how they are used.=20 With that as a backdrop here is a quote from Sams Teach Yourself C++ in = 24 Hours, third Edition by Jesse Liberty.=20 -------------------------------------------------------------------------= ------- When you call a delete on a pointer, the memory it points to is freed. = Calling delete on that pointer again will crash your program! When you = delete a pointer, set it to 0 (null). Calling delete on a null pointer = is guaranteed to be safe. For example Animal: *pDog =3D new Animal; delete pDog; // frees the memory pDog =3D 0; // sets the pointer to null // . . . delete pDog; // harmless -------------------------------------------------------------------------= ------- But it does not work that way. As a matter of fact with both the = Bloodshed/GNU compiler supplied with the book and VC++ 6.0 it works just = the opposite. The book uses this program to demonstrate allocating and = deleting a pointer.=20 -------------------------------------------------------------------------= ------- // Listing 9.4 // Allocating and deleting a pointer #include <iostream> int main() { int localVariable =3D 5; int * pLocal=3D &localVariable; int * pHeap =3D new int; if (pHeap =3D=3D NULL) { std::cout << "Error! No memory for pHeap!!"; return 1; } *pHeap =3D 7; std::cout << "localVariable: " << localVariable << "\n"; std::cout << "*pLocal: " << *pLocal << "\n"; std::cout << "*pHeap: " << *pHeap << "\n"; delete pHeap; pHeap =3D new int; if (pHeap =3D=3D NULL) { std::cout << "Error! No memory for pHeap!!"; return 1; } *pHeap =3D 9; std::cout << "*pHeap: " << *pHeap << "\n"; delete pHeap; return 0; } =20 -------------------------------------------------------------------------= ------- If you compile and run the program the output is as advertised in the = book; localVariable: 5 *pLocal: 5 *pHeap: 7 *pHeap: 9 However if you modify the code by setting pHeap to null and call delete = on pHeap immedately after as shown below. The program still runs without = error.=20 -------------------------------------------------------------------------= ------- // Listing 9.4 // Allocating and deleting a pointer #include <iostream> int main() { int localVariable =3D 5; int * pLocal=3D &localVariable; int * pHeap =3D new int; if (pHeap =3D=3D NULL) { std::cout << "Error! No memory for pHeap!!"; return 1; } *pHeap =3D 7; std::cout << "localVariable: " << localVariable << "\n"; std::cout << "*pLocal: " << *pLocal << "\n"; std::cout << "*pHeap: " << *pHeap << "\n"; delete pHeap; delete pHeap; // Try to crash program pHeap =3D new int; if (pHeap =3D=3D NULL) { std::cout << "Error! No memory for pHeap!!"; return 1; } *pHeap =3D 9; std::cout << "*pHeap: " << *pHeap << "\n"; delete pHeap; return 0; } -------------------------------------------------------------------------= ------- If set pHeap to null, however, and then try to assign *pHeap a value, as = shown below, the program will crash.=20 -------------------------------------------------------------------------= ------- // Listing 9.4 // Allocating and deleting a pointer #include <iostream> int main() { int localVariable =3D 5; int * pLocal=3D &localVariable; int * pHeap =3D new int; if (pHeap =3D=3D NULL) { std::cout << "Error! No memory for pHeap!!"; return 1; } *pHeap =3D 7; std::cout << "localVariable: " << localVariable << "\n"; std::cout << "*pLocal: " << *pLocal << "\n"; std::cout << "*pHeap: " << *pHeap << "\n"; pHeap =3D 0; *pHeap =3D33; pHeap =3D new int; if (pHeap =3D=3D NULL) { std::cout << "Error! No memory for pHeap!!"; return 1; } *pHeap =3D 9; std::cout << "*pHeap: " << *pHeap << "\n"; delete pHeap; return 0; } -------------------------------------------------------------------------= ------- I have several questions. 1.. How could someone who is expert enough to write a beginning book = on C++ make such an error=20 2.. Is it perhaps because the ANSI/ISO definition of the language = and what a compiler should do has changed?=20 3.. Have GNU and the Gates crowd made similar unilateral changes to = solve a pesky problem?=20 4.. Did I misread something which seems fairly straight forward?=20 5.. Are there other pointer inconsistances hiding in the weeds = waiting to pounce on the unsuspecting? |
|
From: Brian P. <br...@su...> - 2002-04-08 22:45:52
|
Dear all: For those newbies out there, the moral of this story is NEVER,ever, EVER delete a pointer without afterwards assigning it NULL (0). I have received numerous emails from beginners and experts alike who have not done this and have experienced some of the following horrific events: (The names have been withheld to protect the guilty) A New York man claimed that his under-ware spontaneously sprung up over his head nearly suffocating him. A woman claimed her cat (fluffy) gave a load meow and died on the spot. A 17 year-old from Vancouver,BC said a meteor crashed through his house and destroyed his computer and lobotomized his dog. A man, hard of hearing, claimed that he gained his hearing back...only to lose his sight. A CA professor found himself stranded on a desert Isle with six other (slightly neurotic) passengers. Finally (and this is the worse by far) a gentleman was forced to port an entire beginners C++ book to Ada simply for pointing out grammatical inconsistencies dealing with pointers in C++ books. There are many more, but they are worse then these and there may be children reading this list. So, don't call delete on an already deleted pointer unless you first assign it null. Period! b-- On Mon, 2002-04-08 at 14:45, Bob Wilson wrote: (Please see the rest of this thread for the gory details). |
|
From: Ioannis V. <no...@ho...> - 2002-04-08 23:42:24
|
> -----Original Message----- > From: dev...@li... > [mailto:dev...@li...] On Behalf > Of Brian Pribis > Sent: Tuesday, April 09, 2002 12:46 AM > To: Dev-C++ User Mailing List > Subject: Re: [Dev-C++] Deliberate crashes - more information > > > There are many more, but they are worse then these and there may be > children reading this list. So, don't call delete on an > already deleted > pointer unless you first assign it null. Period! Why call delete an an already deleted pointer in the first place and why to assign it to zero and call delete on it? :) Ioannis * Ioannis Vranos * Programming pages: http://www.noicys.cjb.net * Alternative URL: http://run.to/noicys |
|
From: Ioannis V. <no...@ho...> - 2002-04-08 23:41:00
|
Yes and to clarify the issue more here what is written in "The C++ Programming Language" 3rd Edition or Special Edition by Bjarne Stroustrup (the creator of C++) (this is the Bible of C++): On page 128: "The delete operator may be applied only to a pointer returned by new or to zero. Applying delete to zero has no effect". And for delete[] some lines down: "Applying delete[] to zero has no effect". But in general you should know whether the pointer points to allocated memory or not. And for bullet-proof code try using the C++ containers instead. Ioannis * Ioannis Vranos * Programming pages: http://www.noicys.cjb.net <http://www.noicys.cjb.net/> * Alternative URL: http://run.to/noicys -----Original Message----- From: dev...@li... [mailto:dev...@li...] On Behalf Of Bob Wilson Sent: Monday, April 08, 2002 11:46 PM To: Dev-C++ User Mailing List Subject: [Dev-C++] Deliberate crashes - more information Ladies and gentlemen: Earlier I posted an lengthy "treatise" on problems related to quote from Sams Teach Yourself C++ in 24 Hours, third Edition by Jesse Liberty. Since that posting I have exchanged several lengthy emails with the author concerning what I perceived as a problem with the wording of his warning. During the corse of the day, I believe we have come to an understanding. Mr. Liberty has asked that I inform the readers of the Dev-C++ User Mailing List of the results of this discussion. He was concerned that my comments would make people think that he had "got this wrong." To that end, I am forwarding the entire thread of our correspondance in reverse cronological order. |