C++ Check if array created with 'new' - c++

In C++ the delete[] is supposed to be used with arrays created by new. You can pass arrays into functions like this: void method_with_array(int* array). How can you tell if an array created this way was created with new, so you can delete it properly.

You can't, so better not pass around pointers to things created with new or new[]. Use for example std::vector or if you really really really need a dynamically allocated array, std::unique_ptr<T[]>.

Usually a good rule is that whoever takes care of the allocation of an object should take care of releasing the object.
That said, if you are allocating and deleting the memory for an object in the same object/container/manager, you know what you are dealing with. In case the same pointer is used for one or multiple elements, you have different options:
keep a variable that tells you which kind of int* member you have allocated
allocate all the times an array, eventually of size 1
use an std::vector even for storing a single element, as above.

Related

array class member with different size for each class instance

I would like to have a class that contains an array member, but the constructor lets me set the size of an array member.
Is this doable? I do not thing I need dynamic allocation, since once the class instances are created, there is no need for the array to change size, it is just that each class instance will have a different size.
Despite several comments suggest that this would be impossible, it is actually not impossible.
The simplest way, of course, is to use an indirection and allocate the array during construction just the normal way (with a = new type[size] and calling delete[] a - not delete a - in the destructor).
But if for some reason you really do not want to have the array data being allocated separately from your object, you can use placement-new to construct your object into a pre-allocated buffer that is large enough to contain all your elements. This avoids a separate allocation for your array and you can still have dynamic size.
I would not recommend using this technique, though, unless you really have a demanding use case for it.

C++ When to use pointer to vector?

I have a problem about pointer and standard library use.
Let's create a new class
class Graph
{
std::vector<Edge> *edge_list;
//another way is
//std::vector<Edge> edge_list;
}
I already thought two reasons why I use pointer:
It's easy to manipulate the memory using new and delete
It can be passed by parameters easily.
However, we can pass by reference if we use vector.Then Reason 2 doesn't count.
So, Is it true if I am not strict with memory allocation, I don't need to use pointer to vector and other std container?
The implementation of std::vector contains 2 pointers:
The beginning of the allocated array
1 element after the end of the allocated array
Essentially, when you declare a vector it has no space allocated in the heap, but as you add elements this changes.
Note that std::vector manages the memory it uses, so there is no need for you to worry about new and delete (unnecessary complexity). As soon as it goes out of scope, it deallocates its memory (stack and heap).
As you said, a vector can be passed very easily by reference, which works the same way as a pointer for machine code, and it's more clear.

Do you need to de-allocate an array of primitives?

If I have an array of a primitive type for example: int A[] = new int[10];
Would it create a memory leak if not freed?
This is a question that popped into my head recently. I'm sure I learned it in school, but it's been such a long time since I've used C/C++ I can't remember exactly. As it was, creating any object with "new" puts that object on the heap which must be freed/destroyed at some point. I remember doing this with arrays of objects and it would make sense to do so, but I don't ever remember needing to free an array of int or String. So is this case with primitive arrays as well?
thanks
Will
If you allocate something with new, and it isn't handed off to a smart-pointer or something for management, you have to delete it. It doesn't matter whether it's an object or a primitive type.
Be careful with the word "free" here. You shouldn't use the function free on anything that was allocated with new. Also make sure you understand the difference between delete and delete[].
Even better, use std::vector instead of dynamic arrays and you don't have to worry about deleting anything.

Safe array deletion

I'm new to C++ and i'm not absolutely sure how to deal with arrays and pointers in a safe way. In my class I got a member called items:
Item * items;
in my class method called read() I open a file and read the items from this file. I allocate the space accordingly:
items = new Item[item_count];
item_count is given as a variable in the file and is read in advance before creating any items. In the deconstructor in my class I release the memory like this again:
delete[] items;
But if i call the method read() twice before my deconstructor is executed the memory for the first array will not be released properly. I would like to release it in the read method in advance before allocating new memory. But how do I check if some memory is already allocated for the array items?
EDIT: I know there are many other possibilities out there with more 'modern' approachs and more comfortable solutions. But in this case we where explicitly told to use pointers and arrays (education purpose only).
In modern C++, "the safe way" is to avoid raw pointers and raw arrays entirely.
Declare your variable like this:
std::vector<Item> items;
Allocate the space like this:
items.resize(item_count);
In the deconstructor in your class, no code is necessary to release this memory. It's handled automatically.
The reuse of items that you describe in your question will work.
Unless you have some strong reason not to do so, just use std::vector for arrays in C++:
#include <vector> // for std::vector
....
std::vector<Item> items;
In this way, you don't have to explicitly call delete[] to release vector items' resources; it's just done automatically thanks to vector's (and Items') destructors.
This helps building code that is structurally incapable of leaking resources.
You can create a vector of itemCount Items using something like:
std::vector<Item> items(itemCount);
or you could dynamically resize the vector using its resize() method, e.g.:
items.resize(itemCount);
In c, normally you initialize the pointer to NULL so you can check whether or not it points to valid memory, and then after deallocation you immediately set it back to NULL.
Failing to do so, may cause problems, like dereferencing an already deallocated pointer (they're called dangling pointers), so you must be careful.
In c++ you should use nullptr which is equivalent to c's NULL.
Also, there are smart pointers in c++, i.e. pointers that can do this automatically.
Edit: (the answer above was edited) as suggested from the comments, and although this same idea is correct, you should not use NULL in c++, instead use nullptr which has the same functionality, but takes care about the fact that in c++ void * is not automatically converted to any other pointer type like in c.
This Stack Overflow Answer has the details, and also an example that would definitevely convince you and me to use nullptr instead.

A destructor - should I use delete or delete[]?

I am writing a template class that takes as an input a pointer and stores it. The pointer is meant to point to an object allocated by another class, and handed to the this containing class.
Now I want to create a destructor for this container. How should I free the memory pointed to by this pointer? I have no way of knowing a priori whether it is an array or a single element.
I'm sort of new to C++, so bear with me. I've always used C, and Java is my OO language of choice, but between wanting to learn C++ and the speed requirements of my project, I've gone with C++.
Would it be a better idea to change the container from a template to a container for an abstract class that can implement its own destructor?
If you don't know whether it was allocated with new or new[], then it is not safe to delete it.
Your code may appear to work. For example, on one platform I work on, the difference only matters when you have an array of objects that have destructors. So, you do this:
// by luck, this works on my preferred platform
// don't do this - just an example of why your code seems to work
int *ints = new int[20];
delete ints;
but then you do this:
// crashes on my platform
std::string *strings = new std::string[10];
delete strings;
You must document how this class expects to be used, and always allocate as expected. You can also pass a flag to the object specifying how it should destroy. Also look at boost's smart pointers, which can handle this distinction for you.
Short answer:
If you use [] with new you want to use [] with delete.
//allocate some memory
myObject* m = new myObject[100];
//later on...destructor...
delete m; //wrong
delete[] m; //correct
That was the bare bones, the other thing you could look at is boost. Also quite difficult to answer considering you are not sure if its an array or single object. You could check this though via a flag telling your app whether to use delete or delete[].
As a general development rule, you should stick to a design where the class which calls new should also call delete
You shouldn't delete it at all. If your class takes an already initialized pointer, it is not safe to delete it. It might not even point to an object on the heap; calling either delete or delete[] could be disastrous.
The allocation and deallocation of memory should happen in the same scope. Which ever code owns and initializes the instance of your class is also presumably responsible for initializing and passing in the pointer, and that is where your delete should be.
Use delete if you allocated with new.
Use delete[] if you allocated with new[].
After these statements, if you still have a problem (maybe you want to delete an object that was created by someone else), then you are breaking the third rule:
Always delete what you created. Corollary, never delete what you did not create.
(Moving my comment into an answer, by request.)
JonH's answer is right (about using array destruction only when you used array construction), so perhaps you should offer templates: one for arrays, one not.
The other answer is to avoid arrays and instead expect a single instance that may or may not be a proper collection that cleans up after itself, such as vector<>.
edit
Stealing blatantly from Roger Pate, I'll add that you could require the use of a smart pointer, which amounts to a single-item collection.
If you have a class that takes a pointer it's going assume ownership of, then the contract for the use of the class needs to include one of a couple things. Either:
the interface needs to indicate how the object the pointer is pointing to was allocated so the new owner can know how to safely deallocate the object. This option has the advantage of keeping things simple (on one level anyway), but it's not flexible - the class can't handle taking ownership of static objects as well as dynamically allocated objects.
or
the interface needs to include a mechanism where a deallocation policy can be specified by whatever is giving the pointer to the class. This can be as simple as providing a mechanism to pass in a functor (or even a plain old function pointer) that will be called to deallocate the object (preferably in the same function/constructor that passes in the pointer itself). This makes the class arguably more complicated to use (but having a default policy of calling delete on the pointer, for example, might make it as easy to use as option 1 for the majority of uses). Now if someone wants to give the class a pointer to a statically allocated object, they can pass in a no-op functor so nothing happens when the class wants to deallocates it, or a functor to a delete[] operation if the object was allocated by new[], etc.
Since pointer in C++ does not tell us how it was allocated, yes, there's no way to decide what deallocation method to use. The solution is to give the choice to the user that hopefully knows how the memory was allocated. Take a look at Boost smart ptr library, especially at shared_ptr constructor with second parameter, for a great example.
A smart pointer like boost shared_pointer already has this covered, could you use it? linky
Put simply, given only a pointer to dynamically allocated memory there is no way of determining how to de-allocate it safely. The pointer could have been allocated in any of the the following ways:
using new
using new []
using malloc
using a user defined function
etc.
In all cases before you can deallocate the memory you have to know how it was allocated.