What is a heap? (using 'new') - c++

You cannot return an address of something that is defined locally so you must allocate memory on the 'heap' for this element to be placed so that other functions in the program may access it. Can someone explain this in more detail please.
MyClass* myFunc()
{
MyClass* pMC = new MyClass;
return pMC;
}
What is the purpose of the * in the function name? What is this indicating?
I realize that there is a creation of a pointer of type MyClass and it points to a new allocation on the 'heap' of this object. I just fail to understand what exactly the usefulness of this is.

What it means is that the object will always exist until it is explicitly destroyed.
Handling this destruction yourself is an immensely bad idea for a large number of reasons, and there exist a number of schemes that automatically clean it up at various points- unique or shared ownership, for example. This means that code which uses new directly is very bad, and triply so for new[], delete, or delete[].
In unique ownership, there is one pointer (std::unique_ptr<T>) which owns the object, and when it is destroyed, the object is destroyed. This is move-only. In shared ownership, when any (std::shared_ptr<T>) which points to the object is alive, the object remains alive. When the last one is destroyed, the object is also destroyed.

Related

std::make_shared(), std::weak_ptr and cyclic references

My question is about this claim:
If any std::weak_ptr references the control block created by std::make_shared after the lifetime of all shared owners ended, the memory occupied by T persists until all weak owners get destroyed as well, which may be undesirable if sizeof(T) is large. Source
I read here, that this object live until last weak_ptr is present.
Does it free object made with make_shared, with cyclic reference to self or it will live in memory forever?
For example:
struct A
{
std::weak_ptr<A> parent;
}
void fn()
{
auto a=std::make_shared<A>();
a->parent = a;
} // Will it destroy here or not?
It is destroyed. That's one of the reason why weak_ptr exists.
When a is destroyed, the reference counter becomes 0, so the object is destroyed. That means the destructor of the object is called, which destroys a->parent too.
Don't confuse destruction with deallocation. When reference counter becomes 0, or no shared_ptr owns the object, the object is destroyed. If there is any weak_ptr which points the control block, the memory won't be deallocated - because the object was allocated with std::make_shared - but the object is definitely destroyed.
Problem involve with:
If any std::weak_ptr references the control block created by std::make_shared after the lifetime of all shared owners ended, the memory occupied by T persists until all weak owners get destroyed as well, which may be undesirable if sizeof(T) is large
is something like
std::weak_ptr<A> global;
void foo()
{
auto a = std::make_shared<A>();
global = a;
}
So global point to control block of a.
Here even if a is destroyed, the memory used by a is still present to allow the control block to exist.
There is a cycle of object reachability via implementation pointers, that is, you can follow pointers used inside of the private implementations of these objects and go back to where you started: a->parent contains a pointer to the meta information (control block) created either by std::shared_ptr or by std::make_shared.
Of course std::make_shared is expected to minimize the number of dynamic memory allocations by putting together the meta information and the managed object, but that has no bearing on when the managed object is destroyed (which is the only observable aspect since no class specific operator new/operator delete was used). So whether the control block is collocated with the managed object, or has a pointer to that object allocated separately, is irrelevant.
In all but a handful of degenerate cases (where the smart pointer is constructed with a fake deleter that doesn't deallocate anything), the end of the lifetime of the last shared owning smart pointer causes a deleter to run, usually:
of the form delete p; to run, where p is the argument of type T* of the constructor of std::shared_ptr<U>,
or of the form p->~T(), where p is the result of new (buff) T in std::make_shared<T>().
In either case, the value of p can be obtained from the meta information.
[Note that the value p to be deleted is never obtained from the U* pointer value stored in any particular std::shared_ptr<U> instance, as such pointer value may not be "deletable", as the destructor may not be virtual (as long as the pointer argument std::shared_ptr<U> has the right static type: it's sufficient that delete p; where p is the value of the type passed to the templated constructor), as the pointer may be to a member subobject or a complete different complete object, if an aliasing constructor was used to construct another std::shared_ptr with shared ownership.]
So having a pointer to the control block usually allows one to recover a pointer to the controlled object, although that pointer to the complete object cannot be obtained through the public interface (except that the pointer is passed to the deleter, so the only way to recover the pointer in C++, if it was lost, would be to have passed a custom deleter and wait for it to be called). The pointer can certainly be recovered by navigating inside the memory representation (although that navigation might need to use dynamic_cast to a type unknown at compile time, something the debugger will be able to do as long as it knows about all derived classes).
So we have the cycle:
a
a->parent
parent->control_block
control_block.deleter (virtual call or stored function)
deleter.a
if the pointer is stored in a dynamically created deleter, as is necessary to create std::shared_ptr<U>(T*), or
a
a->parent
parent->control_block
control_block.buffer
for objects created with a single allocation make_shared: the object was constructed inside that buffer so &control_block.buffer == a.
But cycles of pointers are not an issue, only cycle of ownership as it implies "self ownership controlled by lifetime", that is "I will destruct myself only when my lifetime will be over" (aka "I will enter destructor when I will have entered destructor"), an absurdity.
Here there is no ownership as a weak reference only owns the meta information, not the information.

Can i delete a statically defined variable using delete operator? [duplicate]

I have an object with a vector of pointers to other objects in it, something like this:
class Object {
...
vector<Object*> objlist;
...
};
Now, Objects will be added to list in both of these ways:
Object obj;
obj.objlist.push_back(new Object);
and
Object name;
Object* anon = &name;
obj.objlist.push_back(anon);
If a make a destructor that is simply
~Object {
for (int i = 0; i < objlist.size(); i++) {
delete objlist[i];
objlist[i] = NULL;
}
}
Will there be any adverse consequences in terms of when it tries to delete an object that was not created with new?
Yes, there will be adverse effects.
You must not delete an object that was not allocated with new. If the object was allocated on the stack, your compiler has already generated a call to its destructor at the end of its scope. This means you will call the destructor twice, with potentially very bad effects.
Besides calling the destructor twice, you will also attempt to deallocate a memory block that was never allocated. The new operator presumably puts the objects on the heap; delete expects to find the object in the same region the new operator puts them. However, your object that was not allocated with new lives on the stack. This will very probably crash your program (if it does not already crash after calling the destructor a second time).
You'll also get in deep trouble if your Object on the heap lives longer than your Object on the stack: you'll get a dangling reference to somewhere on the stack, and you'll get incorrect results/crash the next time you access it.
The general rule I see is that stuff that live on the stack can reference stuff that lives on the heap, but stuff on the heap should not reference stuff on the stack because of the very high chances that they'll outlive stack objects. And pointers to both should not be mixed together.
No, you can only delete what you newed
Object* anon = &name;
When name goes out of scope, you will have an invalid pointer in your vector.
What you're actually asking is whether it's safe to delete an object not allocated via new through the delete operator, and if so, why?
Unfortunately, this is obfuscated by some other problems in your code. As mentioned, when name goes out of scope, you're going to end up with an invalid pointer.
See zneak's answer for why your original question doesn't result in a safe operation, and why the scope for name actually matters.
This will not work - if you delete an object that wasn't allocated by new you've violated the rules or the delete operator.
If you need to have your vector store objects that may or may not need to be deleted, you'll need to keep track of that somehow. One option is to use a smart pointer that keeps track of whether the pointed to object is dynamic or not. For example, shared_ptr<> allows you to specify a deallocator object when constructing the shard_ptr<> and as the docs mention:
For example, a "no-op" deallocator is useful when returning a shared_ptr to a statically allocated object
However, you should still be careful when passing pointers to automatic variables - if the vector's lifetime is longer than the lifetime of the variable then it'll be refering to garbage at some point.

Pointer Ownership

I have an array of pointers: pArray[rows][columns], where each element can contain a pointer to an object. Some of the objects were instantiated in main() on the heap, and some were instantiated by objects themselves also on the heap: That is, I passed pArray to an object member function, and that function created a new object, and put a pointer to it in pArray.
Now when I want to delete pointers to objects from pArray, is there ownership in play here? Meaning, if an object created a new object and placed a pointer to it in pArray, can only the creator object call delete on that pointer? Or can I do it from main(), and other objects by passing the array to them?
Some more details:
The code simulates a predator prey model on a grid (pArray). So I begin by reading in the initial grid config from a file, and instantiate objects (predators, and prey), on pArray from main(). But predators and prey can breed, so objects spawn new objects and by passing pArray to them, they instantiate their children on pArray.
With raw pointers ownership is purely a concept. As long as you are working with raw pointers, it is entirely up to you to assign ownership of pointed object to anyone and anything. It is a matter of your design. There's no such "rule" that the object should be deleted by whoever created them. Ownership can be retained or passed on. Ownership can be shared (as in reference-counted ownership schemes). Again, it is a matter of your design and your intent.
Various smart pointer classes will help you to express your intent and implement your intent. With raw pointers you have to remember who owns what and do everything manually.
No, there is no "ownership" on pointers in C++, if the pointer is valid (contains proper reference to data / object), you can deallocate it anywhere issuing delete command.
The destructor of objects is subject to the same public/protected/private like every other method. So, if the destructor is public, anyone can call delete on the object.
The only important thing is that it happens exactly once, and only after nobody is using the object anymore.
There is no ownership concept for pointers in C++ .As far as I understood your question, Yes you can delete that object from main() in case of dynamic memory allocation. The memory allocated to that object would only be freed only when the program ends or the Object array goes out of scope and the destructor for the class is called.

Will the smart pointer or scoped pointers delete an object when the class has no destructor

Will the smart pointer or scoped pointers delete an object when the class has no destructor
If not, why not just leave the scope and let the object be deleted by itself?
All class members are deleted even if you don't have a destructor when the instance is deleted. Memory leaks occur when you deal with pointers:
class A
{
private:
B* b;
};
In this case, b itself will be destroyed when the instance of A is deleted, but the memory it points to will not.
class A
{
private:
SmartPtr<B> b;
};
In the case of smart pointers, which usually have some reference counting and memory cleanup in the destructor, the memory it points to will be explicitly destroyed by its destructor, and the destructor of the smart pointer will be implicitly called when the instance of the containing class is destroyed.
yes. that s what smart pointers are used for.
http://www.boost.org/doc/libs/1_48_0/libs/smart_ptr/smart_ptr.htm
http://en.wikipedia.org/wiki/Smart_pointer
What is a smart pointer and when should I use one?
Yes, smart pointer deletes the object irrespective of whether class has destructor or not. Note that smart pointers are used with objects allocated on heap (using new) and these object won't release memory when they go out of scope, you need to explicitly delete them. Smart pointers will remove this process of explicitly deleting them.
The pointer to the object itself will be deleted. However if there is any dynamically allocated data in the class it will not get freed. The idea of having a destructor is to be able to post-process the class object and mainly - free any resources taken.
new and delete do two things.
new allocates memory and gets an object to construct itself in that memory space.
delete first gets the object to destruct itself then releases the memory.
Note that some smart pointers can be given a custom deleter which doesn't call delete on the object but whatever you ask it to do. There may be occasions when you wish to pass it a no-op.
Your point is well taken; there aren't that many uses for smart pointers
in C++, since most of the time where they might be relevant, you'd be
better off using value semantics, and copying. In the case of
scoped_ptr, the most frequent use is when the actual object is
polymorphic:
scoped_ptr<Base> pObj = condition
? static_cast<Base*>( new Derived1 )
: static_cast<Base*>( new Derived2 );
(Regretfully, at least one of the static_cast is necessary.)
If you are dealing with a container of polymorphic objects, you'll need
shared_ptr instead, and if you're returning a polymorphic object, or
otherwise passing it around, you will use unique_ptr if you can
guarantee its availability, and auto_ptr otherwise—in some cases
where you're passing it around, shared_ptr might be more appropriate.
In the case of returning an object or passing it around, the cost of
copying it might also be a motive for using a smart pointer, even if the
object isn't polymorphic. In such cases, I'd still use value semantics
(i.e. copying and assigning the object itself) unless I had a
performance problem.
Note that smart pointers aren't only used for memory management. I
regularly use auto_ptr in the interface of queues between threads:
once the object has been inserted into the queue, it no longer belongs
to the sending thread; auto_ptr expresses these semantics exactly,
with the auto_ptr in the sending thread becoming invalid. Or a
modifiable singleton (something which should be very, very rare) might
acquire a lock in its instance function, and return a shared_ptr
which frees the lock in its final destructor. I've also used smart
pointers in one or two cases to ensure transactional semantics: in one
case, for example, the objects were in a number of different sets (which
held pointers to them, of course), ordered according to different
criteria. To modify an object, you acquired a shared pointer to it; the
function which returned this shared pointer also removed the objects
from the sets, so that you could safely modify the key values as well,
and the final destructor reinserted them into the sets according to the
new keys. And so on—there are any number of uses for smart
pointers that have nothing to do with memory management or object
lifetime.

Is it possible to delete a non-new object?

I have an object with a vector of pointers to other objects in it, something like this:
class Object {
...
vector<Object*> objlist;
...
};
Now, Objects will be added to list in both of these ways:
Object obj;
obj.objlist.push_back(new Object);
and
Object name;
Object* anon = &name;
obj.objlist.push_back(anon);
If a make a destructor that is simply
~Object {
for (int i = 0; i < objlist.size(); i++) {
delete objlist[i];
objlist[i] = NULL;
}
}
Will there be any adverse consequences in terms of when it tries to delete an object that was not created with new?
Yes, there will be adverse effects.
You must not delete an object that was not allocated with new. If the object was allocated on the stack, your compiler has already generated a call to its destructor at the end of its scope. This means you will call the destructor twice, with potentially very bad effects.
Besides calling the destructor twice, you will also attempt to deallocate a memory block that was never allocated. The new operator presumably puts the objects on the heap; delete expects to find the object in the same region the new operator puts them. However, your object that was not allocated with new lives on the stack. This will very probably crash your program (if it does not already crash after calling the destructor a second time).
You'll also get in deep trouble if your Object on the heap lives longer than your Object on the stack: you'll get a dangling reference to somewhere on the stack, and you'll get incorrect results/crash the next time you access it.
The general rule I see is that stuff that live on the stack can reference stuff that lives on the heap, but stuff on the heap should not reference stuff on the stack because of the very high chances that they'll outlive stack objects. And pointers to both should not be mixed together.
No, you can only delete what you newed
Object* anon = &name;
When name goes out of scope, you will have an invalid pointer in your vector.
What you're actually asking is whether it's safe to delete an object not allocated via new through the delete operator, and if so, why?
Unfortunately, this is obfuscated by some other problems in your code. As mentioned, when name goes out of scope, you're going to end up with an invalid pointer.
See zneak's answer for why your original question doesn't result in a safe operation, and why the scope for name actually matters.
This will not work - if you delete an object that wasn't allocated by new you've violated the rules or the delete operator.
If you need to have your vector store objects that may or may not need to be deleted, you'll need to keep track of that somehow. One option is to use a smart pointer that keeps track of whether the pointed to object is dynamic or not. For example, shared_ptr<> allows you to specify a deallocator object when constructing the shard_ptr<> and as the docs mention:
For example, a "no-op" deallocator is useful when returning a shared_ptr to a statically allocated object
However, you should still be careful when passing pointers to automatic variables - if the vector's lifetime is longer than the lifetime of the variable then it'll be refering to garbage at some point.