-1

I saw a game developer overload the new and delete operator on YouTube. His name is Cherno.

void* operator new(size_t size){
    return malloc(size);
}
void operator delete(void* pointer, size_t size){
    free(pointer);
}

Well, now what I did is I created a class:

struct MyClass{
    int my_int;
    MyClass(int a): my_int{a}{}
    ~MyClass(){cout << "MyClass is destructed" << endl;}
};

And I created a heap allocated object of that class in the main() function

int main(){
    MyClass* cls = new MyClass{10};
    // free(cls);    //Doesn't call the destructor
    delete cls;      //Does call the destructor
    return 0;
}

Output:

MyClass is destructed

So, here is my question. Why does the delete call the destructor and the free() doesn't, even if all delete does is that it uses the free() internally (I assume).

And I know that we shouldn't use free() on objects that are allocated using new operator. But even in this case the new operator uses malloc() internally

Artaza Sameen
  • 519
  • 1
  • 5
  • 13
  • Because `delete` destroys objects and `free` only deallocates memory. `free`, like `malloc`, is a C function and knows nothing about C++. – molbdnilo Jun 09 '21 at 12:07
  • Note that `operator new` and `operator delete` are for allocating and deallocating memory (they should really be called something like "allocate" and "deallocate", but C++ avoids adding keywords as far as possible). They do not correspond directly to the new-expression and delete-expression. – molbdnilo Jun 09 '21 at 12:08
  • 1
    You need to distinguish between `operator delete` and `delete` _expression_. Basically, `delete` expression = destruction + `operator delete`. – Daniel Langr Jun 09 '21 at 12:08
  • 1
    `malloc` and `free` are C functions. They know nothing about C++ objects and how they work. `new` and `delete` OTOH, are C++ constructs and know how to deal with classes. – NathanOliver Jun 09 '21 at 12:13
  • It simply isn't possible. `free` doesn't know what type of pointer it's being passed, so it couldn't call a destructor even if it wanted to. – Mark Ransom Jun 09 '21 at 12:50

1 Answers1

2

Calling free on a pointer that was not created by call to std::malloc, std::calloc, std::aligned_alloc, or std::realloc is undefined behavior. Hence you cannot expect anything reasonable from your program, because you allocated memory for your MyClass object with operator new.

docs

pptaszni
  • 5,591
  • 5
  • 27
  • 43
  • 1
    Technically, objects are not allocated. Only their storage is allocated. Objects are then initialized (constructed) in this storage. – Daniel Langr Jun 09 '21 at 12:11
  • @ArtazaSameen, yes I read your full question, but you are wrong. "And I know that we shouldn't use free()" - it is not that "you shouldn't do this". If you do, it is UB. – pptaszni Jun 09 '21 at 12:13
  • 2
    you clarified one misunderstanding but the question you answer not. Why does `free` not call the desctructor? It has been iterated several times in comments, but the answer does not mention it – 463035818_is_not_an_ai Jun 09 '21 at 12:27
  • @463035818_is_not_a_number, well sorry; I thought that "free doesn't call DTor because it is [UB](https://en.cppreference.com/w/cpp/language/ub)" is what we are looking for, and I don't see it mentioned in the comments. According to UB definition, if compiler decides to throw `std::runtime_error("free called on ptr returned by new");` in this situation, it will still be according to the standard. – pptaszni Jun 09 '21 at 12:35
  • free not calling destructor has nothing to do with the UB in OPs code. OPs code is just not a good example for the question they are asking. Anyhow, i think OP already got what they wanted from the duplicate (and mentioning UB is a nice addition that isnt mentioned explicitly in the dupe). – 463035818_is_not_an_ai Jun 09 '21 at 12:39
  • @pptaszni well if something is undefined behavoiur, then it is obvious that we shouldn't do it. – Artaza Sameen Jun 09 '21 at 13:11