如果代码如下:
int *p=new int (20);
delete []p;
这样时正确的我可以理解,为什么在编译器里运行如下代码同样是正确的呢?
int *p=new int (20);
delete p;//同样正确,原因呢?
…………………………………………………………………………………………………………
9.3 10:11更新
看到下面大家的解答稍微有些认识了,假如有类people
people *p=new people(20)
这个作何解释呢?
people *p=new people[20]
这个是对象数组,数组的大小为20.
Maybe it’s a typo, or maybe you misunderstood: maybe the parentheses after int should be square brackets?
In the above code snippet, p1 should be released using delete, and p2 should be released using delete[].
This will happen
未定义行为
if new and delete do not correspond.Specific to your environment, if you confirm that both situations are executed normally and there is no memory leak, you can explain it as follows:
However, this is still a case in point
未定义行为
that different compiler implementations handle this differently, andthe C++ standard makes no guarantees.
In addition to the link given by @harttle, the discussion in this link is also worth referring to: http://stackoverflow.com/questions/6953457/delete-and-delete-are-the-same-when-deleting-arrays
I understand what you mean. Do you think that
delete
(notdelete[]
) for arrays and single elements should be able to compile, right? It really shouldn't be. There is no such problem in modern programming languages. The problem lies in C++'s array pointer degradation.C++ was originally started by Stroustrup to implement the object-oriented mechanism. For efficiency reasons, a new type system was not designed, but was extended based on C (C with classes). In this way, C++ inherits some low-level language features of C. For example: Arrays cannot be passed through parameters or return values, and pointers are always passed. As for whether the pointed content is an array or an element, the responsibility for maintenance falls on the developer.
The array name will be downgraded to the first element pointer in most cases, so the array name and element pointer have mutually compatible types. For example:
So
delete
an array anddelete
a pointer are syntactically exactly the same. So the compiler won't throw any errors, but runtime will throw undefined behavior . For more discussion of thedelete
form, see http://harttle.com/2015/08/07/effective-cpp-16.htmlUpdated at 2015-9-4 00:20
The above answer is about why the compiler does not give warnings or errors, because the array name and element pointer are type-compatible. Now let’s add “What exactly happens when
delete
anddelete[]
are called?”Usually the
delete
keyword can be regarded as a function call + memory recycling process. You can override (override) the function call:The process of delete
Calls the
rawMem
destructor of the object on the memory pointed to by the parameter pointer . Of course, the destructor of a polymorphic class is generally a virtual function. In a normal implementation, all destructors at the class level will be called cascadingly. This is done by the compiler, beforeoperator delete
above.operator delete
completes the default (or customized) memory recycling, usually calling thefree
keyword. Even if you don't overloadoperator delete
, C++ provides a global implementation.The process of delete[]
Get the length N of the array. Different compilers have different implementations here, and the basic data types and objects are also different. The compiler may store an array length in the array header ( so the array size may be greater than the sum of the element sizes, and the first element address is not necessarily equal to the array address! ).
Iteratively call these N destructors.
operator delete
Release the memory of N elements.Incorrect use
If
delete
is used to recycle an array, ordelete[]
is used to recycle elements, the runtime behavior is undefined. That is to say, the compiler can implement it however it wants. The C++ standard does not specify how to handle this situation.But generally speaking,
delete
an array of primitive types will not have particularly bad effects. The biggest problem is that the subsequent memory is not recycled. Butdelete
an object array often causes the program to exit abnormally. For example:On Mac with Homebrew gcc 5.1.0 there is a runtime error:
In short, if you use
new
to apply for memory, usedelete
to recycle it; if you usenew []
to apply for memory, usedelete[]
to recycle it. This all depends on consciousness, the compiler will not care about you.No error reported does not mean there will be no errors.
Simply put,
delete []p
will perform the destruction operation of all objects in the p array one by one, butdelete p
will not.Search for more details yourself.
Isn’t this applying for an int space and initializing the value to 20? .
Do you want to say this?
This is the application array
p just points to a pointer. Whether it points to a single element or an array is up to the developer. The compiler will only release the array as the address of the array when [] is included