3

Possible Duplicate:
Are memory leaks “undefined behavior” class problem in C++?

Never calling delete or delete[] on address returned by new or new [] resp in a C++ program is an Undefined Behavior or merely a memory leak?

References from the Standard(if any) are welcome.
This came up in one of the comments here & I am just a bit confused about it.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 3
    Why would you consider it undefined behavior. I have not seen anything in the standard that would indication that this would lead to this conclusion. Asking to prove a negative is not possible (you can only prove positives). – Martin York Mar 29 '12 at 07:39
  • UB that only occurs at the end of time? – David Schwartz Mar 29 '12 at 07:41
  • @DavidSchwartz No, not even then. – BЈовић Mar 29 '12 at 07:45
  • @LokiAstari: Well, as I already mentioned *I am just a bit confused about it.* And I clearly stated *References from the Standard(if any)*. I don't see what is wrong in asking the question? And I don't see how it deserves downvotes or criticsm just for the sake of it. – Alok Save Mar 29 '12 at 07:52
  • @sharptooth That holds for c++03. What about c++11, and 3.8/4? – BЈовић Mar 29 '12 at 08:05
  • @VJovic: That question will surely benefit from ur answer covering C++11 3.8/4 – sharptooth Mar 29 '12 at 08:08
  • @Loki: so you're claiming that there does not exist any proof of a negative. Can you prove that? ;-) – Steve Jessop Apr 02 '12 at 09:48
  • @SteveJessop: I can prove that not all negatives can not be proved. So because my statements was in English (and thus inexact) I can prove that I was wrong. – Martin York Apr 02 '12 at 14:40
  • @Loki: you're right about the important part, though: it's difficult to be sure there isn't some obscure clause in the standard saying something to the effect of, "if your nickname is Als, then behavior is undefined on Thursdays". – Steve Jessop Apr 02 '12 at 14:55
  • @SteveJessop: Rather amusing,but I failed to see the humor if was intended so. – Alok Save Apr 02 '12 at 14:59
  • @SteveJessop: I forgot the smiley face :-) I tried to write a proof but it turned into an essay on kicking cats (as my old professor explained it using this analogy). But I could not get it correct and thus it seemed very cruel. – Martin York Apr 02 '12 at 15:09

7 Answers7

9

The standard is clear with regards to the semantics of new and delete. There's certainly no undefined behavior if you don't call delete; it is, in fact, standard practice for singletons, and I imagine that std::cout and std::cin use new[] to acquire their buffers (which they almost certainly never delete). Why would not calling delete be undefined behavior?

What is undefined behavior is calling the wrong form of delete, calling free for memory allocated with new, or in general to attempt to delete an object without following the protocol required by its allocation.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • 1
    @Als Obviously, if you need the semantics of the destructor, then you need to delete the object. Just as obviously, if you don't want the semantics of the destructor, then you're better off not calling delete. The quoted passage doesn't say anything that common sense wouldn't tell you. – James Kanze Mar 29 '12 at 08:17
  • +1 I understand the point you are trying to make through your comments.I believe all those comments put together with the quote @VJovic added answers my Q conclusively.Thanks. – Alok Save Mar 29 '12 at 14:03
9

[basic.life] (3.8 Object lifetime) in paragraph 4 tells :

A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

BЈовић
  • 62,405
  • 41
  • 173
  • 273
  • +1 - now define "depends on". – Mankarse Mar 29 '12 at 08:06
  • +1 - This conclusively says it is an UB, Unless someone proves "depends on" makes it inapplicable to the issue at hand. – Alok Save Mar 29 '12 at 08:15
  • 8
    @Als This conclusively says that it isn't undefined behavior, **unless** your program logic depends on something which you've implemented in the destructor. Most destructors don't have side effects, so the paragraph doesn't apply at all. But even for those that do, your code may not depend on them to function correctly. – James Kanze Mar 29 '12 at 08:19
  • Thanks, to your answer coupled with @JamesKanze, comments my Q stands answered,Since You were the one to provide the Standard Quote I will accept your answer. – Alok Save Mar 29 '12 at 14:09
  • 1
    Furthermore, this quote only applies to the case where the memory is reused or released without invoking the destructor. I'm not certain that program-exit constitutes "reusing or releasing" the memory. Obviously from the POV of the OS, the memory will be released, but I think that lies outside the scope of the running program and hence outside the scope of the C++ standard. – Steve Jessop Apr 02 '12 at 09:50
1

Referring to [basic.stc.dynamic.deallocation] (aka 3.7.4.2 in n3337) there are only 4 paragraphs.

  1. operator delete and operator delete[] should be either class members or in global scope
  2. Precisions on the valide signatures of operator delete and operator delete[]
  3. Precisions on which delete can be used for deallocation, depending on which new was used for allocation
  4. Precisions on the possible arguments value and effects of the call (ie the pointers to this storage are now invalid)

There is absolutely no note here on what would happen if storage is allocated but never released.

I don't think that the Standard concerns itself with this, so it is more unspecified rather than undefined.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • Not calling `delete` in itself does not provoke undefined behavior. Waiting for a destructor call does will never occur does. VJovic definitely got the right citation. – Matthieu M. Mar 29 '12 at 08:41
0

It's just a memory leak.

But I explicitly remember the standard saying that use new with delete[] and new [] with delete is undefined behavior. (or any combination with malloc or free)

I don't think the standard specifically says calling new results in undefined behavior if you fail to call delete. Also, how can the run-time tell if you call delete sometime later or never call it at all?

I don't think there are any contracts in the standard that say - if you do X, you MUST do Y afterwards, otherwise it's UB.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • It's not even necessarily a memory leak. It may be intentional, so that the object can continue to be used during program shutdown. – James Kanze Mar 29 '12 at 07:42
  • @JamesKanze it's debatable. :) Even intentional, I don't see how it's not a memory leak. I understand what you mean, I'm just saying that even though the object lives until the end of the run, but is not released... maybe that too is a memory leak? I know the OS reclaims the memory, but... well... semantics – Luchian Grigore Mar 29 '12 at 07:44
  • @JamesKanze: When OS has to release your object (because you didn't free/delete it), it is leak. The leak, however, can be intentional. – SigTerm Mar 29 '12 at 07:47
  • 1
    A memory leak is code which leaks memory. Constantly. The fact that you don't delete something is not a memory leak in itself; the fact that you continually allocate things that you don't delete is. A memory leak is a fatal error, sooner or later. And arguably, short lived programs like compilers can't leak (and I've seen one compiler, written in C, that never called `free`). – James Kanze Mar 29 '12 at 08:08
  • @SigTerm The OS always has to clean up your memory, since `operator delete` doesn't normally return memory to the OS anyway. – James Kanze Mar 29 '12 at 08:10
  • And with regards to the last paragraph in the original answer: the standard can't make such a demand, since the concept of "afterwards" is too fuzzy---what about programs which "never" terminate? (Never is in quotes because, of course, all programs will terminate sometime, if only when the computer they are running on fails.) – James Kanze Mar 29 '12 at 08:12
  • @JamesKanze: Let's distinguish between application-level leaks and OS_level leaks. Application-level leaks will be fixed by OS once program terminates. OS-level leak will not be fixed by OS when program terminates and will damage the system (for example, allocating many files could be an OS_level **resource** leak). So, when I say/write "leak", I mean "application-level leak". And everything that isn't deleted by app - even a single allocation - goes into "application leak" category. Even if it is intentional. – SigTerm Mar 29 '12 at 08:16
  • I am afraid this does not answer my Q.The second para states a well known fact completely irrelevant to the Q asked, the second is a speculatory statement & the last para is irrelevant.That leaves the first para, which merely states it is either.Not convincing enough to me. – Alok Save Mar 29 '12 at 08:18
  • @Als well it's impossible finding something that doesn't exist in the standard. I'm just providing arguments for why I believe it's not UB. – Luchian Grigore Mar 29 '12 at 08:20
  • @JamesKanze I posted a question here - http://stackoverflow.com/questions/9921590/is-not-calling-delete-on-a-dynamically-allocated-object-always-a-memory-leak – Luchian Grigore Mar 29 '12 at 08:21
  • @SigTerm How is it "leaking"? The word "leak" has a very clear meaning in everyday speech, and I have yet to see any special technical meaning for it which is unrelated to this meaning. In particular, allowing a finite quantity of water to escape from a pail is _not_ a leak; a leak is when water constantly escapes (even if very slowly). You've invented some imaginary meaning for leak that I can't follow: it more or less makes the word meaningless. – James Kanze Mar 29 '12 at 08:24
  • @JamesKanze: Leak is both verb and noun. And as a noun it means an "way for fluid to escape from container". When you do not delete/free something, you have such "hole" ini your code. Anyway, regardless of your opinion/reasoning, there's a traditional meaning associated with "memory leak". What you describe isn't it. If you think it's not logical, think of it as a specific jargon. – SigTerm Mar 29 '12 at 08:40
0

Let's say that if you do not call delete your program will still work. BUT if you do not delete memory allocations your program memory usage will keep growing until your program will run out of free memory (the longer you run it better are the chances for it to happen) which will cause crashes at different points and will be very hard to detect (and I think that whats 'Undefined Behavior' mentioned in the comment means)

giorashc
  • 13,691
  • 3
  • 35
  • 71
  • UB has a very specific meaning in the context of C++, and that meaning is exactly what the commenter had in mind there. – Jon Mar 29 '12 at 07:42
  • First, it's perfectly normal for some allocations never to be deleted. A memory leak is when you retain allocated memory that will never be used. And it's not undefined behavior for a program to run out of heap---the standard requires `new` to throw an `std::bad_alloc`. (Of course, some systems use a common space for heap and stack, and using too much heap can cause stack overflow, which is undefined behavior.) – James Kanze Mar 29 '12 at 07:44
0

I dont see how not releasing memory will lead to undefined behaviour. If you dont clean up, the OS still has knowledge of the allocated memory. That will lead to a resource leak for as long as the application runs.

fduff
  • 3,671
  • 2
  • 30
  • 39
  • 1
    Not true. It will lead to a resource leak during the _life_ of the application, after exit it will be returned to the OS (and any modern OS will be able to retrieve _all_ memory after process exit), even if not all memory got `delete`'d. – orlp Mar 29 '12 at 07:42
  • yes that's right nightcracker, the resource leak will only happen during the lifetime if the application. Resources will be reclaimed when the application ends. – fduff Apr 11 '12 at 10:58
0

If delete/delete[] is not called for the objects allocated with new/new[], there would be resource leaks. It could be memory leak if the constructor had allocated dynamic memory. Other things like semaphore lock not released, file handles not released etc can happen if the constructor had allocated them.

It will not be undefined behavior.

Sanish
  • 1,699
  • 1
  • 12
  • 21
  • This does not answer my question. – Alok Save Mar 29 '12 at 08:13
  • 1
    @Als This answer tells you that delete can do more than _just_ memory deallocation. Resources controlled by the object might not be deallocated. For example, The constructor might remove the safety latch on a radioactive rod in a nuclear power station whilst moving the rods into or out of the core. The destructor could be where the latch is reapplied. Important. – Peter Wood Mar 29 '12 at 12:30
  • @PeterWood: It makes a good point which I already know and fails to answer the Q that I asked.My Q was **not** whether `delete` *only* deallocates memory or not. – Alok Save Mar 29 '12 at 14:03