Do I need to explicitly free the memory in managed C++? - c++

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 :)

Related

Do i need to free allocated memory from local pointers in c++?

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>();
//...
}

Do C++ compilers generally "optimize" malloc and free to new and delete?

If I'm writing 100% ANSI C but compiling in .cpp files will the compiler automatically "optimize" malloc and free calls to new and delete? Does that even make sense given their differences? I didn't think this is how it worked but a friend of mine said this is what happens.
C++ is very specific in c.malloc:
The functions calloc(), malloc(), and realloc() do not attempt to allocate storage by calling ::operator new().
The function free() does not attempt to deallocate storage by calling ::operator delete().
There's a bit of an ambiguity in the question.
int *ip1 = malloc(sizeof int);
int *ip2 = new int;
Those two in fact do the same thing: create an uninitialized value on the heap and assign its address to the pointer on the left-hand side.
But:
struct S { /* whatever */ };
S *sp1 = malloc(sizeof S);
S *sp2 = new S;
Those two don't necessarily do the same thing. If S has a constructor, new S will allocate memory and call the constructor; malloc(sizeof S) will only allocate memory.
I mentioned an ambiguity. There's another possible meaning for "replace new, and that is using calls to operator new:
struct S { /* whatever */ };
S *sp1 = malloc(sizeof S);
S *sp2 = ::operator new(sizeof S);
On the surface, by default these two do the same thing: they allocate memory on the heap for an object of type S and return a pointer to that memory; neither one initializes the object. But there's an important difference. If malloc can't allocate memory it returns a null pointer. If operator new can't allocate memory it throws an exception of type std::bad_alloc (there's more to it than that, but that's enough difference for now).
That's also true for new S: it throws an exception if it can't allocate memory, while malloc returns a null pointer.
Do C++ compilers generally “optimize” malloc and free to new and delete?
No.
Optimizing is an act that reduces the workload of your program.
Since new and delete invoke constructors and destructors respectively, while malloc() and free() do not, it makes no sense to optimize them.
Usually new will call malloc(), which also adds to my point above, as mentioned in Does ::operator new(size_t) use malloc()?
PS: "I'm writing 100% ANSI C" is not going to make a C++ compiler happy in any way...

Dynamically allocating memory on stack

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.

Can a call delete on the pointer which is allocated with the placement new?

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.

Which to use - "operator new" or "operator new[]" - to allocate a block of raw memory in C++?

My C++ program needs a block of uninitialized memory and a void* pointer to that block so that I can give it to a third party library. I want to pass control of the block lifetime to the library, so I don't want to use std::vector. When the library is done with the block it will call a callback that I have to supply and that will deallocate the block. In C I would use malloc() and later free().
In C++ I can either call ::operator new or ::operator new[] and ::operator delete or operator delete[] respectively later:
void* newBlock = ::operator new( sizeOfBlock );
// then, later
::operator delete( newBlock );
Looks like both ::operator new and ::operator new[] have exactly the same signature and exactly the same behavior. The same for ::operator delete and ::operator delete[]. The only thing I shouldn't do is pairing operator new with operator delete[] and vice versa - undefined behavior. Other than that which pair do I choose and why?
Use new with a single object and new[] with an array of objects. So, for example:
int* x = new int; // Allocates single int
int* y = new int[5]; // Allocates an array of integers
*x = 10; // Assignment to single value
y[0] = 8; // Assignment to element of the array
If all you are doing is allocating a memory buffer, then allocate an array of char as in:
int bufferlen = /* choose a buffer size somehow */
char* buffer = new char[bufferlen];
// now can refer to buffer[0] ... buffer[bufferlen-1]
However, in C++, you should really use std::vector for arbitrary arrays, and you should use std::string for character arrays that are to be interpreted or used as strings.
There is no reason to invoke ::operator new or ::operator new[] explicitly rather than using the ordinary syntax for these calls. For POD and primitive types (e.g. char) no initialization will take place. If you need to get a void* buffer, then simply use static_cast to convert char* to void*.
The advantage of the C++ new operators over C's malloc() and free() is that the former throws an exception if there is not enough memory, rather than returning NULL.
Regarding choosing new(size) and new[] for character buffers, I'd advocate the latter since it is less likely to surprise people maintaining the code later i.e. char* buf = new char[size] and delete[] buf.
The values in the buffer will not be initialised, and there is no range-checking - you have to build a nice C++ object to do that for you, or use an existing object such as std::vector or std::string.
The question cannot be answered sensibly.
Firstly, it is said that the program 'needs' a block of uninitialized memory but, from the code sample given, it seems that the program 'needs' a block of uninitialized and UNTYPED memory which seems not very C++ or OO.
Secondly, a std::vector gives sole and automatic control over a block of typed memory that may or may not change in size according to its use. You can lose this control if an instance of std::vector is created on the heap and tracked with raw pointers just as for any other C or C++ object such as a void* memory block.
Thirdly, what is the intended use of this memory block? The answer to this may or may not dictate the use of operator new or operator new[]. In the design of this program, is there a single interpretation of this memory block? What ownership semantics do you require, if any? Etc, etc.
for allocating memory to array/list use new[] other than that use new...