Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

If we allocate an object of size 1 as below

int *arr = new int[1];

Should we delete the object using operator delete[] or operator delete?

The reason I am concerned is if the compiler would be smart enough to convert the statement as a single element allocation int *arr = new int which would cause calling operator delete[] UB.

User Case:

I have a pointer, which I would end up allocation in a varied ways but would finally like to get it deleted. So was wondering, for single element allocation, if I consistently use int *arr = new int[1] can I consistently and safely use operator delete[]

Note

Can you please refer me back to the standards to support your answer?

share|improve this question
5  
operator delete[] of course. int[1] is not int. Compiler smart enough won't convert the statement. – johnchen902 yesterday
2  
It is the same place in the standard that tells you to call delete[] after new[]. there is no special case for size 1. – juanchopanza yesterday
1  
If the compiler was smart enough to do that (though changing one type into another hasn't anything to do with smartness at all), it would have to inform you of this change or this change would have to be specified in the standard and in this case it wouldn't be smartness either, but mandatory. If it was silently behind the back then that compiler wasn't smart but intentionally evil. No need for any standard document apart form common sense, an int just is not the same as an int[1]. Is a one-element array still an array (hint: answer hidden in this comment)? – Christian Rau yesterday
3  
It's probably worth pointing out, too, that there are practically no known cases where you should use new[]. – James Kanze yesterday
2  
This is a silly question. It doesn't matter how "smart" a compiler is, it cannot introduce undefined behaviour (1.9 [intro.execution] p5) and require the programmer to alter source code that is correct, and you already know that using delete[] with new[] is correct and required by the standard. Such an optimisation by a "smart" compiler would mean the program works on one compiler and not another. That way madness lies. – Jonathan Wakely yesterday

6 Answers

up vote 10 down vote accepted

You must use delete[] and not delete. The compiler is not allowed to change new int[1] to new int.

(As int is a POD type it's quite possible that new int and new int[1] do exactly the same thing under the covers, but if this is the case then delete[] on and int* and delete on an int* will also do exactly the same thing.)

ISO/IEC 14882:2011 5.3.5 [expr.delete] / 2:

In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined.

As int[1] is an array object, if you try and delete it with delete and not delete[], the behavior is undefined.

share|improve this answer
Can you please refer me back to the standards? – Abhijit yesterday
@Abhijit: It's not stated in the standard, so I can't give you a section number, but for the same reason it's not allowed. – MSalters yesterday
In addition to the delete-expression restrictions, there are restrictions to the Standard Library deallocation function: "Otherwise, the behavior is undefined if the value supplied to operator delete(void*) in the standard library is not one of the values returned by a previous invocation of either operator new(std::size_t) or operator new(std::size_t, const std::nothrow_t&) in the standard library [...]" (+ the same for the array (de)alloc) [basic.stc.dynamic.deallocation]/3 – DyP yesterday

The rule is quite simple:

  1. always balance a new with a delete
  2. always balance a new[] with a delete[]

otherwise you get undefined behaviour.

There are no exceptions; even new[1] must be balanced with a delete[], and new[0] must be deleted as the compiler can still reserve storage.

share|improve this answer
2  
IIRC, new[0] wasn't allowed. – chris yesterday
IIRC? whassthat? – Bathsheba yesterday
If I recall correctly. I don't see anything from a quick standard sweep, though, so perhaps I remembered wrong or ran into a faulty compiler error, or perhaps I was thinking of a normal array. – chris yesterday
2  
1  
It seems to work fine in any form for me. I really think it was stack-allocated arrays I was thinking of. – chris yesterday
show 1 more comment

Should we delete the object using operator delete[] or operator delete?

operator delete[]. You have allocated an array of ints, so there's no other option for correctly deallocating it. Using operator delete would invoke undefined behavior.

share|improve this answer

You must use delete[].

C++11 5.3.5 Delete

::opt delete cast-expression

::opt delete [ ] cast-expression

The first alternative is for non-array objects, and the second is for arrays.

An array holding one element is still an array.

share|improve this answer
int *arr = new int[1];

Since you use [] for allocation, you need to use [] for deleteas well.

Memory leaks

The objects created by new expressions (objects with dynamic storage duration) persist until the pointer returned by the new expression is used in a matching delete-expression.

So you should use delete[] for releasing the memory or else you get undefined behaviour.

And (incase), if the complier is smart enough to take int * arr = new int[1] as int, It must be smart enough to take delete[] arr on arr as delete arr. However, there is nothing for delete to differentiate between the arr from int*arr = new int[1] and int*arr = new int. The [] in delete is going to indicate it.

share|improve this answer

No its not safe, it may leads to some unwanted situations.
For example,It is possible in a memory to have some data (int/char/float...) next to the location where your pointer points to. At that time if you used delete [] then it may try to delete that data too if it is an integer,for other data types it leads to unexpected errors.

Example:

int *ptr = new int;
int a = 20;
char c = 'e';
*ptr = 10;
delete [] ptr;

There is a possibility the c and a variables may store next to the location where the pointer ptr points to, If a is stored next to it, then it deletes "a" also, if the other data types are present, leads to unexpected runtime results.

So it's advised to use delete[] only for the deletion of memory allocated using new datatype[].Hope this is useful.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.