Heap crash when overloading new and delete [duplicate] - c++

This question already has answers here:
How could pairing new[] with delete possibly lead to memory leak only?
(10 answers)
Closed 6 years ago.
I am getting heap crash in delete call of overloaded delete. Please help me in resolving this issue.
class number {
int *series;
public:
void* operator new(size_t size){
number *n = ::new number;
n->series = new int[size];
printf("new %p %p\n", n, n->series);
return n;
}
void operator delete(void *ptr) {
number *n = (number*)ptr;
printf("delete %p %p\n", n, n->series);
delete (int*)n->series;// why crash here?
::delete n;
}
};
int main() {
number *n= new number;
delete n;
return 0;
}

You allocated series as an array, using new int[size]. So you must free it as one: delete [] n->series.
(I'm not sure why to have the cast there, but it's a bad idea. If you tell the compiler to ignore your errors it just makes things harder.)

Related

return pointer with new operator. Where to put delete?

Im fairly new to C++.
So I learned that new allocates memory and returns a pointer of my datatype. But can I use this in a function and return the pointer? If so then where should I place the delete operator?
Is the following code legal?
int *makeArray(int size)
{
int *result = new int[size];
delete[] result;
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... */
return 0;
}
It is compiling and working but logically it makes no sense because I deleted my array.
So I tried the following:
int *makeArray(int size)
{
int *result = new int[size];
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... do some stuff with pointer */
delete[] pointer;
return 0;
}
Is this safe or does it cause a memory leak? Is there a better way of returning the pointer?
I tried both versions and they are compiling and working but I'm sure at least one of them if not both are unsafe.
Is the following code legal?
int *makeArray(int size)
{
int *result = new int[size];
delete[] result;
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... */
return 0;
}
Definitely not! This is Undefined behavior because you return a deleted pointer. After using the delete operator you're telling your OS that it can release the memory and use it for whatever it wants. Reading or writing to it is very dangerous (Program crashing, Bluescreen, Destruction of the milky way)
int *makeArray(int size)
{
int *result = new int[size];
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... do some stuff with pointer */
delete[] pointer;
return 0;
}
Is this safe or does it cause a memory leak?
Yes this is the correct way of using the new and delete operator. You use new so your data stays in memory even if it gets out of scope. Anyway it's not the safest code because for every new there has to be a delete or delete[] you can not mix them.
Is there a better way of returning the pointer?
YES. It's called Smart Pointer. In C++ programmers shouldn't use new but smart pointer at all. There is a C++ community Coding Guideline to avoid these calls Guideline R11

Delete vs Delete[] in a custom operator in C++ (different than common delete vs delete[] questions)

I define a class called MyNewDeleteAllocator and define custom new and delete operators for the class. This code has no bugs whatsoever and works perfectly fine. However, I have a question about line 29 of my code. It seems that changing "delete[]" to "delete" does not change anything in my code results.
I am aware of the difference between delete (single object when allocated by "new") and delete[] (array of objects allocated by "new[]").
I was wondering why interchanging delete and delete[] here on line 29 did not affect my results.
#include <new>
#include <iostream>
using namespace std;
//Allocator class
class MyNewDeleteAllocator {
public:
MyNewDeleteAllocator() {}
~MyNewDeleteAllocator() {}
static void* operator new (size_t size);
static void operator delete (void* p);
};
void* MyNewDeleteAllocator::operator new (size_t size) {
void* p;
p = malloc(size);
if (p == NULL) {
//Throw bad_alloc.
std::bad_alloc exception;
throw exception;
}
cout << "MyNewDeleteAllocator::operator new called with size_t " << size << endl;
return p;
}
void MyNewDeleteAllocator::operator delete (void* p) {
cout << "MyNewDeleteAllocator::operator delete called. " << endl;
delete[] p; //THIS IS LINE 29
}
int main()
{
MyNewDeleteAllocator* p = new MyNewDeleteAllocator; //Create MyNewDeleteAllocator object.
delete p; //Delete MyNewDeleteAllocator object.
return 0;
}
First of all, this is not an allocator, or your name convention is wrong. In C++, an allocator allocates memory for a given type, not for raw bytes. More on that - https://en.cppreference.com/w/cpp/memory/allocator
Second, don't mix malloc()/delete and new/free(). malloc() should be used with free(), new with delete, not the other way around. More on that - https://stackoverflow.com/a/20488420/12979560
So, all you need to do is to replace malloc() with new. Also, when you use new, C++ will throw std::bad_alloc in case if it can't allocate the requested memory.

Why compilers do not assign NULL to pointer variable automatically after deleting dynamic allocated memory? [duplicate]

This question already has answers here:
Why doesn't delete set the pointer to NULL?
(12 answers)
Why doesn't free(p) set p to NULL?
(9 answers)
Closed 5 years ago.
I have small piece of code:
#include <iostream>
using namespace std;
int main()
{
int *p = new int(10);
if(p != NULL)
{
cout<<"Deleted dynamic allocated memory"<<endl;
delete p;
}
if(p == NULL)
{
cout<<"NULL"<<endl;
}
else
{
cout<<"Not NULL"<<endl;
}
return 0;
}
After deleting dynamic allocated memory using delete operator, Why compilers do not assigned NULL to pointer(like p = NULL) automatically?
It would often be unnecessary, particularly in well-written code.
It could hide away bugs.
delete p; would be syntactically idiosyncratic if it modified its argument.
On (1) it would be particularly wasteful with std::unique_ptr.
In other words, burdening the programmer with this job if necessary is the right thing to do.
Because it is extra work (= more clock cycles, less performance), that is usually not needed.
If your design calls for NULLing a pointer to indicate that it no longer points at something useful, you can add code to do that. But that should not be the default, because it can be insufficient and pointless.
NULL pointers don't solve every possible problem:
int *ip = new int;
int *ip1 = ip;
delete ip;
if (ip1)
*ip1 = 3; // BOOM!
And they are often pointless:
struct s {
int *ip;
s() : ip(new int) {}
~s() { delete ip; } // nobody cares if ip is NULL, 'cause you can't see it
};
They are allowed to do so, but it isnt mandatory. I think the reason they dont do it consitently is because anyhow you cant rely on it. For example consider this:
int* a = new int(3);
int* b = a;
delete a;
/// ....
if (b != 0) { /// assume b is either null or points to something valid
std::cout << *b; /// ups
}

Should i use delete[] in a function? [duplicate]

This question already has answers here:
Is not calling delete on a dynamically allocated object always a memory leak?
(6 answers)
Closed 6 years ago.
void work() {
int *p;
p=new int[10];
//some code....
}
I have a short question that in the work function, should i use delete[] operator? since when work function is over, p will be destroyed, which is wrong or right ? (My English is bad, i am sorry).
This will work as long as the code throws no exceptions...
void work() {
int *p;
p=new int[10];
//some code....
delete [] p;
}
This is better (but difficult to maintain):
void work1() {
int *p;
p=new int[10];
try {
//some code....
} catch(...) {
delete [] p;
}
delete [] p;
}
This is much better...
void work2()
{
auto p = std::unique_ptr<int[]>(new int[10]);
// some code...
// memory is automatically deleted
}
And this is how you should do it...
void work3()
{
auto v = std::vector<int>(10);
// some code...
}
You're right, if you have no reference to p outside of the function, e.g. a global variable, then you need to call delete [] p right inside of the function, otherwise the reference to the allocated memory you want to free is lost.
Yes, if integers are allocated using new int[10], you need to clean up using delete[], since it is an array.
Yes, you need to release the memory from new.
Alternatively with C++11, you can use smart pointer:
void work() {
std::unique_ptr<int[]> p{ new int[10] };
//some code....
// RAII will delete[] magically here
}
Alternatively, if you are using just few integers (10 in your case), that are known in compile time, you can do "normal" or static array. e.g.
void work() {
/* static */ int p[10];
//some code....
}
Alternatively, use std::vector:
void work() {
std::vector<int> p{10};
//some code....
// RAII will delete[] magically here
}
Alternatively, with C++11 if array size is known in compile time, use std::array:
void work() {
std::array<int,10> p;
//some code....
// RAII will delete[] magically here
}

Will delete[] with void* cause memory leak? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is it safe to delete a void pointer?
Will the following code cause memory leak?
void *ptr = new long [10];
delete[] ptr; // note: ptr is a void*
[EDIT]
The code above will generate a warning message during compiling to specify it "undefined".
I ask this cause I'm wondering how does C++ handle memory ranges when delete[] is called.
I should change my question to make it more specified.
Will the following code cause memory leak?
char *ptr = (char *)(new long [10]);
delete[] ptr; // note: ptr is a char*
No. Leaving delete[] out will cause a leak. BTW, it should be long* ptr. I don't think the delete[] will even compile with a void* argument.
I tried the following program (slight modification of this example):
#include <iostream>
#include <new>
using namespace std;
struct myclass {
myclass() {cout <<"myclass constructed\n";}
~myclass() {cout <<"myclass destroyed\n";}
};
int main () {
void * pt = new myclass[3];
delete[] pt;
return 0;
}
using g++ and got the following compilation warning:
leaky.cpp: In function ‘int main()’:
leaky.cpp:13: warning: deleting ‘void*’ is undefined
And when you run it...fail! The process dies (invalid pointer) when you attempt to delete that pointer.