Behaviour of Malloc with Delete in C++

Behaviour of malloc with delete in C++

This is undefined behaviour, as there's no way to reliably prove that memory behind the pointer was allocated correctly (i.e. by new for delete or new[] for delete[]). It's your job to ensure things like that don't happen. It's simple when you use right tools, namely smart pointers. Whenever you say delete, you're doing it wrong.

What if, memory allocated using malloc is deleted using delete rather than free

When you call delete a pointer, the compiler will call the dtor of the class for you automatically, but free won't. (Also new will call ctor of the class, malloc won't.)

In you example, a char array apparently don't have a dtor, so delete does nothing but return the memory. That's why it's okay. (Or vise versa, new a char array and then free it.)

But there can still be a problem: what if new and malloc are borrowing memory from different heap manager?

Imagine that, you borrow money from people A, and return to people B later. Even if you are okay with that, have you ever consider A's feeling?

BTW, you should use delete [] pArray; to free an array allocated using new[].

Does freeing structures in C also delete its members?

The members are part of the structure. Freeing the structure deallocates all of its members.

However, in your example, the members are just pointers. You're copying a pointer into the structure (node->data1 = ...), then out of the structure (... = node->data1), then freeing the structure. None of this affects the memory that the pointer is pointing to.

In your example the actual strings are stored in static memory (they're string literals). That means they're never destroyed; they live as long as the program is running. That's why it's perfectly safe to print them. Your code is fine.

Finally, accessing freed memory has undefined behavior (meaning anything can happen, including a program crash or appearing to work correctly). If you want to access members of a structure that has been freed, just do that:

struct elem *p = malloc(sizeof *p);
free(p);
p->data1 = "boom!"; // Undefined behavior!

However, that would be a bug, so ... don't, please.

What happens on allocating with new [] and deleting with just delete

What happens on allocating with “new []” and deleting with just “delete”

The behaviour of the program is undefined.

Now I expected it to do some memory mishaps

Your expectation is misguided. Undefined behaviour does not guarantee mishaps in memory or otherwise. Nothing about the behaviour of the program is guaranteed.

I mean if this is how it works

This is how you observed it to "work". It doesn't mean that it will necessarily always work like that. Welcome to undefined behaviour.

new, delete ,malloc & free

If you do so you will run into undefined behavior. Never try that. Although new might be implemented through malloc() and delete might be implemented through free() there's no guarantee that they are really implemented that way and also the user can overload new and delete at his discretion. You risk running into heap corruption.

Other than that don't forget that when you call malloc() you get raw memory - no constructor is invoked - and when you call free() no destructor is invoked. This can as well lead to undefined behavior and improper functioning of the program.

The bottom line is... never do this.

Can I mix new and malloc on different redirection?

Yes, you can do that. You must call delete[], delete and free accordingly later on. Be careful to not free something you got from malloc with delete etc.

c++ malloc and free object creation and deletion

Reading so many points from so many I myself wrote a program to explain your problem. See below :-

#include <iostream>
#include <vector>
using namespace std;

class X
{
int x;
vector<int> v;
public:
X()
{
cout<<"constructing\n";
x=0;
v.push_back(1);
v.push_back(2);
}
int& getx()
{
return x;
}
vector<int>& getv()
{
return v;
}
~X()
{
cout<<"destroying\n";
}
};
int main()
{
X* p=(X*)operator new(sizeof(X));
++p->getx();
p->getx()*=5;
cout<<p->getx()<<"\n";
for (int x:p->getv())
cout<<x<<" ";
cout<<"\nexecuted\n";
operator delete(p);
return 0;
}
/* Output :-
5

executed
*/

See how p ignored the vector v and went for the line executed. This is because vector<int> being a class (or more precisely a class template) was never created by operator new (or malloc in your case). Your program showed the output for x because it is a primitive type & not a class. For a class you need a constructor & hence operator new or malloc aren't suitable for classes & hence the output. If you simply replace operator new with new & operator delete with delete then the output will be :-

constructing
5
1 2
executed
destroying

Now your code gives the correct & apt results ! Congo !

For your second question, NEVER MIX UP malloc & free with new & delete as it creates UB with not so happening results.

How could pairing new[] with delete possibly lead to memory leak only?

Suppose I'm a C++ compiler, and I implement my memory management like this: I prepend every block of reserved memory with the size of the memory, in bytes. Something like this;

| size | data ... |
^
pointer returned by new and new[]

Note that, in terms of memory allocation, there is no difference between new and new[]: both just allocate a block of memory of a certain size.

Now how will delete[] know the size of the array, in order to call the right number of destructors? Simply divide the size of the memory block by sizeof(T), where T is the type of elements of the array.

Now suppose I implement delete as simply one call to the destructor, followed by the freeing of the size bytes, then the destructors of the subsequent elements will never be called. This results in leaking resources allocated by the subsequent elements. Yet, because I do free size bytes (not sizeof(T) bytes), no heap corruption occurs.



Related Topics



Leave a reply



Submit