2

Possible Duplicate:
What is the difference between new/delete and malloc/free?

class Foo
   {
    public:
     Foo() { x =  new int; } 
     ~Foo() { delete x; }
    private:
        int *x;
   };

  Foo *p = new Foo[10];
  free ( p );

I am getting confuse with the above code. Is there any problem about it?

Community
  • 1
  • 1
Mnop492
  • 53
  • 1
  • 2
  • 4
  • @sharptooth. Since the question is "above code. ... any problems" This question also required somebody explain what the rule of three is. It is not just a simple mater of delete Vs free – Martin York Apr 13 '11 at 07:55
  • @Martin: Maybe, but this has been addressed here many times just as well. – sharptooth Apr 13 '11 at 08:11
  • @sharptooth: As has free Vs Delete. Its not as if one is more important than the other. They are both issues that need to be explained for the above code. – Martin York Apr 13 '11 at 08:24

6 Answers6

14

When you call free() for an object allocated with new, its destructor is not called, so in this example you get memory leaks. Also, in this example you must use delete[] because memory is allocated with new[].

Michael
  • 53,859
  • 22
  • 133
  • 139
  • That's only the tip of the iceberg. Calling `free()` on a pointer returned by an `operator new` is undefined behavior; anything can happen. And does, in some cases. – James Kanze Apr 13 '11 at 08:07
  • Yeah, I know. But "undefined behavior" sounds a little strange if you want to know the difference. So, I hope my answer will help not to do such mistakes. – Michael Apr 13 '11 at 08:12
6

Yep, there's a huge problem: new (and delete) can be overridden by anyone for any type, and may or may not use malloc as the underlying allocator (really, it probably won't). Meanwhile, §20.4.6/4 of the C++03 standard says:

The function free() does not attempt to deallocate storage by calling ::operator delete().

Meaning, any new invocation may allocate memory in any fashion, but free() will most likely not deallocate it correctly.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
1

If you allocate an object with new, you must deallocate it with delete. free() frees blocks of memory allocated with malloc et al.

dlev
  • 48,024
  • 5
  • 125
  • 132
  • and don't forget something allocated with `new T[]` needs to be deleted by `delete []` – Mat Apr 13 '11 at 05:52
1

Apart from allocating and deallocating memory, the new operator calls the ctor, and the delete operator calls the destructor. The functions malloc and free only allocate and deallocate memory respectively.

Sujay Ghosh
  • 2,828
  • 8
  • 30
  • 47
1

Calling free with an address that wasn't a return value of malloc or calloc is undefined behavior. Clearly, in your example, the destructor of Foo will not be called, but that's in some ways the least of your worries. Literally anything can happen. (In my development environment at home, I use a debugging operator new and operator delete. The address returned by operator new is not the address returned from a call to malloc, and calling free with it can have all sorts of disagreeable effects, including possibly corrupting the free space arena, causing a later crash.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
1

There are a couple of problems with your code:

Obviously the first one is the mixing of free/delete

In C++ code to avoid confusion it is best not to use malloc/free. But if you must then free() can only be used to free pointers created via malloc/calloc/realloc. Pass any other pointer and your program is likely to go boom.

Adding more context to this problem is that the C++ versions new/delete not only allocate/release memory but initialize/de-initialize the object via the constructor/destructor. The destructor is more obscure as it is used to release resources that were created in the constructor. In your case the constructor allocates memory and the destructor deallocates the memory. But since you are using free none of the destructors would get called (so you have a memory leak (in each cell)).

The other problem you have is that the compiler generated versions of the copy constructor and assignment operator (these are two of four methods that can be automatically generated by the compiler for each class) do not work well when you have RAW pointers in your class.

For example:

{
  Foo     a;        // a.x = pointer to a dynamically allocated location
  Foo     b(a);     // b.x = a.x (whoops)

} // Both a and b go out of scope here.
  // This means b's destructor is called
  // Followed by a's destructor (now here is where the problem is)
  // Because b.x = a.x you have now called delete on the same pointer twice.

Double deletion of the same pointer is not allowed.

What you need to do is look up the Rule of Three

But basically when your class contains a RAW pointer you also want to make sure that Copy Constructor/Assignment operator/Destructor are all defined.

So things to remember when allocating memory:

  • new must be matched by a delete.
  • new [] must be matched by a delete [].
  • free() can only be used on the result of malloc/calloc/realloc

Once you have mastered those rules:

  • Try and never use delete.
  • Learn about smart pointers and containers (let them do the work for you).

If your object contains a RAW pointer (which should be rare because you have learn about smart pointers and containers). You must know the rule of three and how to make sure the compiler generated methods do not make a mess of your object accidentally.

Community
  • 1
  • 1
Martin York
  • 257,169
  • 86
  • 333
  • 562