There is such code:
#include <iostream>
int main()
{
int a;
int* p = new (&a) int(2);
std::cout << a << std::endl;
// delete p; error BLOCK TYPE IS INVALID
std::cin.get();
return 0;
}
The output is:
2
Why is it possible to dynamically allocate memory on stack? (I thought that heap is the right place to do this). And, why does delete operator return error in this case, but new operator work?
This is using the placement new syntax. Placement new does not allocate memory at all, rather, it is a way to construct an object at a particular location. In this example, the memory comes from the stack. It doesn't have to. delete has issues because you didn't new the memory.
There are ways to dynamically allocate memory from the stack (alloca) but that's not what is happening here.
int* p = new (&a) int(2);
This is called placement-new. It doesn't allocate memory. It constructs the object in the same memory of a. In placement new, it's the user who specifies the memory region where new operator constructs the object. In your code above, you specify the memory region by writing (&a) expression just after the new keyword. Since &a is not a dynamically allocated memory, you cannot delete it:
delete p; //runtime-error
It would give runtime error, it attempts to delete the memory where the variable a resides.
However, if you dynamically allocate the memory, then you can do delete it. Lets suppose, A is some class, then you should be doing this:
char *buffer = new char[sizeof(A)]; //allocate memory of sizeof(A);
///ASSUMPTION: the buffer is properly align as required by the type A
//use placement-new to construct an object at the specified memory region
A *pA = new (buffer) A(/*..parameters..*/);
//...
//incorrect way to delete the memory!
//delete pA; //incorrect
//before deleting the memory you should be calling the destructor explicitly as
pA->~A(); //call the destructor explicitly - must do it
//now deallocate the memory as
delete []buffer;
This is simplest example of placement-new which explains the syntax only. But the story doesn't end here; it is the beginning and to make it work properly, the memory pointed to by buffer has to be aligned properly for the object type, and in the above example, I simply assumed so. In the real code, you cannot make such dangerous assumption. Now read this FAQ:
What is "placement new" and why would I use it?
This is called placement new: http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10
You can optionally pass an address to new, and it will only call the object's constructor (if it has one). Because no memory was allocated, it would be an error to deallocate it with delete. Simply call the object's destructor (if it has one) and you're done.
C++ separates the notions of memory allocation and object lifetime. This is perhaps one of the most important "new" aspects of the language compared to C. In C there is no such distinction because variables are entirely determined by their memory, while in C++ objects have a more abstract notion of a "state" which is distinct from the underlying memory.
Let's look at memory first:
{
char buf[100]; // automatic allocation, scoped lifetime
}
{
void * p = std::malloc(100); // dynamic allocation, manually managed
void * q = ::operator new(100); // essentially identical
// ...
::operator delete(q); // manual deallocation
std::free(p); // ditto
}
On the other hand, an object's lifetime is a separate topic:
{
Foo x; // automatic storage, scoped lifetime.
// Implies automatic memory allocation for sizeof(Foo) bytes.
}
{
Foo * px = ::new Foo; // dynamic storage, manual lifetime,
// implies dynamic allocation via ::operator new()
Foo * py = ::new (q) Foo; // dynamic storage and manual lifetime, uses memory at q
// ...
delete px; // destroy object _and_ deallocate memory
py->~Foo(); // destroy object. Memory was never our business to start with.
}
As you can see, the separation of memory and object lifetime adds a lot of flexibility: We can have dynamic objects living in automatic memory, or take care of allocation ourselves and reuse memory for repeated object constructions. The standard new and delete expressions combine allocation and construction, but this is only a shortcut for the most frequently used operations. In principle, you're entirely free to handle memory and object lifetime separately.
This idea underpins the notion of allocators, which are a core concept in the C++ standard library.
Related
For instance:
void Func()
{
int* i = new int; // the simplest case
vector<int*> v = new vector<int*>; // another case, not sure if **new** is using correctly here
vector<int*>* vPointer = new vector<int*>;
}
void main()
{
Func();
}
So, if I allocate dynamic memory(by using new operator) for local variables in functions,
Do they live on heap or stack?
when the program exits the function, are they still dangling around on heap or destroyed as function variables?
Can I use new operator on non-pointer types? How to delete (or return back the allocated heap memory) it later?
Thank you!
int i = 3;
this creates an object of type int on the stack. (The C++ standard uses the term "automatic storage", and I'm usually a stickler for proper use of formal terms, but "stack" and "heap" are deeply embedded in programming vocabulary, so "stack" and "heap" are just fine as technical terms).
int *ip = 0;
this creates an object of type int* on the stack. ip holds a null pointer.
int *ip = new int;
this creates an object of type int* on the stack, just like the previous one. It holds a pointer to memory on the heap (see earlier parenthetical; the formal term is "free store"). You know that the memory is on the heap because that's what operator new does.
When you're finished with the heap memory you have to release it:
delete ip;
if you don't delete it and the function that created it returns, the local variable (ip) that held the pointer is gone. The memory has been allocated and it hasn't been freed, so unless you copied the pointer to some place else, you have no way to get at the memory you allocated. That's called a "memory leak".
void f() {
int *ptr = new int;
// is the following line necessary?
delete ptr;
}
int main() {
f();
return 0;
}
Do i have to free the allocated memory in the function f or is it freed automatically because there is no reference to that memory anymore?
Do i need to free allocated memory from local pointers in c++?
If you want to avoid memory leaks - and you should want to - then you should dellacate everything that you allocate. There should be one delete for each allocating new.
or is it freed automatically
Dynamic allocations are not freed automatically.
because there is no reference to that memory anymore?
Whether memory is referenced is irrelevant in regard to whether its memory is deallocated. If dynamic memory is not referenced by anything, then the memory has been leaked. C++ does not have garbage collection.
Some classes do allocate memory and free that allocation in their destructor. This idiom is called RAII (look up the initialism to learn more). A pointer is not a class and it has no destructor. Ending of the lifetime of a pointer has no effect on the pointed object.
You should avoid using bare owning pointers. I recommend to use RAII containers or smart pointers (which are not actually pointers, but classes) to manage the memory instead. Standard library provides those out of the box. Also, avoid dynamic allocation when it isn't needed.
There is hardly ever a need to use new and delete directly, and they should be avoided when possible.
C++ does not have a garbage collector. If you allocate memory dynamically using the new operator, you have to free it using the delete operator.
So, the function will introduce a memory leak if the allocated memory:
int *ptr = new int;
Is not freed before exiting the function.
You can avoid such a problem using smart pointers, for example std::unique_ptr, eg:
#include <memory>
//...
void f() {
std::unique_ptr<int> ptr = std::make_unique<int>();
//...
}
there are quite a few faces for the new operator in c++, but I'm interested in placement new.
Suppose you allocate memory at a specific memory location
int memoryPool[poolSize*sizeof(int)];
int* p = new (mem) int; //allocates memory inside the memoryPool buffer
delete p; //segmentation fault
How can I correctly deallocate memory in this case?
What if instead of built-in type int I would use some class called myClass?
myClass memoryPool[poolSize*sizeof(myClass )];
myClass * p = new (mem) myClass ; //allocates memory inside the memoryPool buffer
delete p; //segmentation fault
Thanks for your help.
In the first case, there's no point in using placement new, since int doesn't have a constructor.
In the second case, it's either pointless (if myClass is trivial) or wrong, since there are already objects in the array.
You use placement new to initialise an object in a block of memory, which must be suitably aligned, and mustn't already contain a (non-trivial) object.
char memory[enough_bytes]; // WARNING: may not be properly aligned.
myClass * c = new (memory) myClass;
Once you've finished with it, you need to destroy the object by calling its destructor:
c->~myClass();
This separates the object's lifetime from that of its memory. You might also have to release the memory at some point, depending on how you allocated it; in this case, it's an automatic array, so it's automatically released when it goes out of scope.
In your case there is no need to deallocate it, your int array will be deallocated once you return from your function. You should only call explicitly your destructor:
p->~myclass();
to keep you buffer correctly aligned use std::aligned_storage, look in here for example:
http://www.cplusplus.com/reference/type_traits/aligned_storage/
I have managed .net C++ dll, a function inside that do the following:
unsigned char* mBytes = new unsigned char[hSize];
How to release this mBytes before return?
For each:
new[] - delete[] should be called
new - delete should be called
malloc() - free() should be called
ref new / gcnew - a memory is deallocated automatically
You should avoid taking care of memory management on your own as much as possible by:
following RAII idiom
prefering objects with automatic storage duration over dynamically allocated ones
taking advantage of smart pointers that will ensure that the memory is freed using the appropriate (explicitly specified) means and it will happen so on every return / exit path (even when an exception is thrown)
etc.
In this case you used new[] for allocation, so you should deallocate this memory by calling:
delete[] mBytes;
Simply use delete[] operator.
delete[] mBytes;
Should do the work.
And delete for dealocating new
Althrough managed c++ can designate class to be collected via garbage collector, by keyword __gc. Eg. class definition:
__gc class gc {
int* i;
char* g;
float* j;
};
See MSDN :)
Can we call delete on the pointer which is allocated with the placement new? If no then why? Please explain in details.
I know that there is no placement delete. But I wonder why just delete opetator can not delete the memory without caring how that memory on which the pointer points is allocated?
delete is doing two things:
Calls destrucor
Frees memory
And I see no reaason for delete not to be able to call either of these two operations on the object which was created by placement new. Any idea about reasons?
You must only call delete on pointers that were created with operator new. If you use placement new with a memory location that was allocated by the normal operator new then you may safely use delete on it (provided you get the types and pointers right). However, you can use placement new on any memory, so you usually will manage that memory some other way and call the object's destructor manually.
For instance, in this convoluted and usually unnecessary scenario, it is safe to delete the memory you used placement new on, but only because you allocated it with new before:
char* mem = new char[sizeof(MyObject)];
MyObject* o = new (mem) MyObject;
// use o
o->~MyObject(); // with placement new you have to call the destructor by yourself
delete[] mem;
However, this is illegal:
char mem[16]; // create a buffer on the stack, assume sizeof(MyObject) == 16
MyObject* o = new (mem) MyObject; // use stack memory to hold a MyObject
// note that after placement new is done, o == mem
// pretend for this example that the point brought up by Martin in the comments didn't matter
delete o; // you just deleted memory in the stack! This is very bad
Another way to think of it is that delete only deallocates memory allocated previously by the normal new. With placement new, you do not have to use memory that was allocated by the normal new, so with the possibility of not having been allocated by normal new, delete cannot deal with it.
EDIT1: I know that there is no placement delete. But I wonder why just
delete opetator can not delete the memory without caring how that
memory on which the pointer points is allocated?
Because each flavour of memory allocation uses some implementation specific tracking of the memory (usually a header block that precedes the user address) and this make the allocation/deallocation to work only when paired up correctly:
new must pair with delete
new[] must pair with delete[] (most implementations though forgive mixing the newand new[])
malloc and frieds must pair with free
CoTaskMemAlloc pairs with CoTaskMemFree
alloca pairs with nothing (stack unwinding takes care of it)
MyCustomAllocator pairs with MyCustomFree
Attempting to call the wrong deallocator will result in unpredictable behavior( most likely seg fault now or later). Therefore calling delete on memory allocated by anything else other than new will result in bad things.
Furthermore the placement new may be called on any address, may not even be an allocated address. It can be called on an address located in the middle of some larger object, it may be called on a memory mapped region, it may be called on a raw virtual committed region, anything goes. delete woul attempt, in all these cases, to do what its implementation tell him to do: subtract the header size, interpret it as a new header, link it back into the heap. Kaboom.
The one that know how to release the memory of a placement new address is you, since you know exactly how was that memory allocated. delete will only do what it knows, and it may not be the right thing.
No, since delete not only calls the destructor but also frees the memory, but if you used placement new you must have allocated the memory yourself using malloc() or stack. You do, however, have to call the destructor yourself. Also see the C++ FAQ.
No. There is no placement-delete expression.
Typical scenario:
void * const addr = ::operator new(sizeof(T)); // get some memory
try {
T * const pT = new (addr) T(args...); // construct
/* ... */
p->~T(); // nap time
}
catch (...) {
}
::operator delete(addr); // deallocate
// this is _operator_-delete, not a delete _expression_
Note that the placement-new operator does have a corresponding delete operator which is mandated to be precisely void ::operator delete(void* [, size_t]) { }, a no-op; this is what gets called if the constructor of T throws an exception.
No, because a placement new doesn't allocate any memory. You use placement new on previously allocated raw memory. The only thing it does is call the constructor of the object.