Vidar Hasfjord said:
[Suppose I have the following code:
int (*p)[5] = (int (*)[5])new int[5];
How do I delete the allocated memory?
As your question has been answered elsewhere, I'll just add an
interesting aside from a language design perspective. If C++ had a
more regular design the type of the "new int [5]" expression would not
degenerate to "int*". A regular design would render the array
overloads of new and delete superfluous, and make your cast here
unnecessary. Consider the irregularity of:
I don't think my question has bene answered, what I was asking was the
difference between each delete invocation, it seems that each is identical
but I get warning for delete *p, see code:
class Base{
public:
Base() {std::cout<<"Constructing base\n";}
~Base(){std::cout<<"Destructing base\n";}
};
int main() {
Base (*pA)[4] = (Base (*)[4])new Base[4];
Base* pB = new Base[3];
std::cout<<"\nDeleting pA:\n";
delete[] pA;
//delete[] *pA;
std::cout<<"\nDeleting pB:\n";
delete[] pB;
If you run the above code you see that each invocation of delete[] produces
the desired effect, even if you use *pA instead of pA. This however gives a
warning but I think the array is converted to a pointer. I did my tests on a
windows platform but it may not be the same on other platforms.
This suggests to me that the pointer-type is not rellevant, on my platform
at least, when calling delete[].
typedef struct {int a, b, c, d, e;} Struct; // aggregate type
typedef int Array [5]; // aggregate type
Struct* ps = new Struct; // Ok!
Array* pa = new Array; // Error! Should be "int* pa".
delete ps; // Ok!
delete pa; // Error! Should be "delete [] pa".
If instead C++ was regular and this was correct code, the type of the
pointer would carry the size information and allow the regular delete
operator to release the correct amount of memory. These irregularities
are avoided by std::array:
Yeah but it's never going to be a regular language, that is not the nature
of comp programming. All you can do is wrap it up in some class and make it
apper like regular syntax. I'm no big fan of unnecessary wrapping.
typedef std::array <int, 5> Array; // aggregate type
Array* pa = new Array; // Ok!
delete pa; // Ok!
Yes but look at all the extra code you need to introduce behind the scenes
to get these semantics. I don't see any advantage in using an STL class over
a pointer in many cases, there are some cases where they are perfect and
really good , but not always.
Dereferencing the pointer, (*pa), gives you a reference (lvalue) to
the array as a whole, and an indexing operator is implemented for the
array class itself (not via degeneration into pointer arithmetic).
Thats simple to achieve without the introduction of a STL class, for
example:
int (*pA)[6] = (int (*)[6])new int[6];
int (&rA)[6] = *pA;
The only advantage I see for using STL vectors is that they are expandable.
If you need a quick fix generic expandable array I agree they are the
solution. But for a simple fixed size array I wouldn't bother with an STL
class.
The new std::array circumvents the numerous irregularities between
pointers and arrays that causes so much confusion. I.e. you can copy
arrays, pass and return arrays by value to and from functions, and the
array will never implicitly convert to a pointer to the first element.
Hence I recommend its use instead of C-style arrays.
I've never really used it TBH, my compiler setup doesn't seem to have that
library.
I don't really see the need for it in most cases, I'm quite happy with
normal C++ arrays, I'm just a bit rusty on C++ so I was trying to confirm
the behaviour of delete[] with the given cases.
TY for your post
Paul.