If a create a pointer with new[] (not just new) must I delete it with delete[] (not just delete).
Printable View
If a create a pointer with new[] (not just new) must I delete it with delete[] (not just delete).
Yes, you must.
delete would just free the memory of the first element
Undefined behaviour. Speculating about what you said, I think it would free all memory, but would call only destructor for first element (though it may probably be smart enough to compare size of class and allocated memory and act indifferent of what was called, but most likely this functionality wouln't be included).Quote:
Originally Posted by Padan
with VC++ 6.0, calling delete when delete[] is required only calls the constructure of the first class then produces an exception. For simple (elementary) data types, such as int, there is no problem, but its not a good idea to use delete then either.
It's not a good idea because it might not produce the correct behaviour on a different compiler. That is what is meant by "undefined" behaviour.
It's never a good idea to call delete when delete[] is required but since the pointer points to the first element of the array the first element should always be freed. Access to the other elements is not possible afterwards.
No, it shouldn't always be freed. It's undefined behaviour.Quote:
Originally Posted by Padan
Not only in this case, you shouldn't use it in the vice versa case, i.e, using delete [] when delete is required. From Item 16: Effective C++, 3rd edition.
Quote:
When you use delete on a pointer, the only way for delete to know whether the array size information is there is for you to tell it. If you use breackets in your use of delete, delete assumes an array is pointed to. Otherwise, it assumes that a single object is pointed to:
What would happen if you use the "[]" form on stringPtr1? The result is undefined, but it's unlikely to be pretty. Assuming the layout above, delete would read some memory and interpret what it read as an array size, then start invoking that many destrucutors, oblivious to the fact that the memory it's working on not only isn't in the array, it's also probably not holding objects of the type it's busy destructing.Code:std::string * stringPtr1 = new std::string;
std::string * stringPtr2 = new std::string[100];
What would hapeen if you didn't use "[]" form on stringPtr2? Well, that's undefined too, but you can see how it would lead to too few destrucotors being called. Furthermore, it's undefined (and sometimes harmful) for built-in types like ints, too, even though such types lack destructors.
The rule is simple: if you use[] in a new expression, you use must [] in the correspoinding delete expression. If you don't use [] in a new expression, don't use [] in the matching delete expression.
Why not using std::vector?Quote:
Originally Posted by RatmilT
here is a good example from a good book.Quote:
Originally Posted by RatmilT
In C++, you can create arrays of objects on the stack or on the heap with equal ease, and (of course) the constructor is called for each object in the array
When creating arrays of objects on the heap using new, there’s something else you must do. An example of such an array is
When creating arrays of objects on the heap using new, there’s something else you must do. An example of such an array is
This allocates enough storage on the heap for 100 MyType objects and calls the constructor for each one. Now, however, you simply have a MyType*, which is exactly the same as you’d get if you saidCode:MyType* fp = new MyType[100];
to create a single object. Because you wrote the code, you know that fp is actually the starting address of an array, so it makes sense to select array elements using an expression like fp[3]. But what happens when you destroy the array? The statementsCode:MyType* fp2 = new MyType;
look exactly the same, and their effect will be the same. The destructor will be called for the MyType object pointed to by the given address, and then the storage will be released. For fp2 this is fine, but for fp this means that the other 99 destructor calls won’t be made. The proper amount of storage will still be released, however, because it is allocated in one big chunk, and the size of the whole chunk is stashed somewhere by the allocation routine.Code:
delete fp2; // OK
delete fp; // Not the desired effect
The solution requires you to give the compiler the information that this is actually the starting address of an array. This is accomplished with the following syntax:
The empty brackets tell the compiler to generate code that fetches the number of objects in the array, stored somewhere when the array is created, and calls the destructor for that many array objects.Code:delete []fp;
See this ;)
std::vector can be used in many places instead of new[], but not all places.Quote:
Originally Posted by NoHero
For example, you cannot assume that std::vector contained objects are contiguous in the memory.
So ((&v[0])+index) is not supposed to point to a valid element.
So, you cannot use std::vector (even if it works with most (if not all) implementations of std::vector) to pass data to a third-party library function, or to some C code, or to some Win32 API.
Also, you cannot assume that two different C++ compilers have the same implementation of std::vector, so exported functions (in binary libraries) must not use std::vector for their functions arguments/return value.
vectors works fine when used inside a project, by using iterators instead of pointers everywhere.
So, depending on the project, std::vector may, or may not be usable.
I am not sure, but maybe in next versions of the STL, std::vector will be assumed to address contiguous memory.
This is Incorrect. It will point to a valid element provided there is one.Quote:
Originally Posted by SuperKoko
Even if I need to pass an array down to WinAPI I use a self written generic container using std::vector() as underlying structure, which can build such an array for me. And since std::vector() is ANSI standard I assume that std::vector() is part of every C++ implementation/compiler.Quote:
Originally Posted by SuperKoko