6

I have the following question:

If I use malloc in a method, return the pointer to my main, and free the pointer in my main, do i have successfully freed the memory or not? And is this bad programming style, if i do so?

int* mallocTest(int size)
{
    int * array = (int*) malloc(size);
    return array;
}

int main ()
{
    int* pArray = mallocTest(5);
    free (pArray);
    return 0;
}

EDIT: The main purpose of this question is that I want to know, if I freed the memory successfully (if i use the right "combination" of malloc-free/new[]-delete[]) when i split this into the method and the main function!

EDIT2: Changed code and topic, to lead to the intended point of the question

print x div 0
  • 1,474
  • 1
  • 15
  • 33
  • 1
    This is wrong (not just bad style; outright broken). Only ever use `malloc` with `free`, `new` with `delete`, and `new[]` with `delete[]`. – BoBTFish Feb 20 '14 at 09:24
  • 1
    Malloc with delete is [covered here](http://stackoverflow.com/questions/10854210/behaviour-of-malloc-with-delete-in-c). Don't do it. – Ray Toal Feb 20 '14 at 09:25
  • I will change the mistakes, to lead to the "right" point of the question – print x div 0 Feb 20 '14 at 09:37

5 Answers5

4

No. Use free to free memory allocated with malloc, delete for single objects allocations with new and delete [] when using new on arrays.

Mixing and matching may appear to work (it's undefined behaviour, and "undefined" included "works fine" and "sort of works fine most of the time, but crashes on thursdays in months starting with M on days that are divisible with 3 or 7 and the operator has shirt with stripes") - and may indeed work on SOME types of systems, but fail on others, depending on exactly how malloc and new and their respective free and delete functions are implemented.

It is fine to call a function that returns a pointer to some memory that is later freed with the appropriate call. It is "nicer" if you actually implement a pair of functions, where one allocates and the other destroys the data. This is particularly important if the data-structure allocated isn't trivial (e.g. you have allocations inside the outer allocation).

Also consider what happens if you decide that "Oh, I'd like to use new int[size]; instead of malloc(size * sizeof(int)); in the mallocTest()". Now every place that calls mallocTest() will have to change so that it calls delete [] instead of free that you corrected it to after reading this answer.

[Just spotted that your code is broken, and probably won't compile, certainly won't allocate space: (int *)malloc[size]; doesn't do what you want it to do, and I'm pretty sure is illegal, as indexing a function is invalid]

And finally, the "best" solution is wrap all allocations in an object, such that the destructor of that object destroys the data allocated within the object. So, for example, use std::vector<int> instead of allocating with malloc.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Thanks for that advice, I didn't know that... But this leaves the question open, if I successfully free the memory, if I use the correct "combination" of malloc-free / new[]-delete[], and split them into method and main? – print x div 0 Feb 20 '14 at 09:30
  • When you correctly match `free()` to `malloc()`, and `delete[]` to `new[]`, then it's guaranteed to work correctly irregardless of how many function calls pass between allocation and freeing of the memory. – Tadeusz A. Kadłubowski Feb 20 '14 at 09:38
  • Thank you a lot for this answer, it was my fault that I didn't double-check my question for this mistake. But as stated in my previous comment, it didn't seemed important for the intention of my question. I fixed the points you mentioned. – print x div 0 Feb 20 '14 at 09:44
4

Mixing malloc freeing it with delete is explained in other answers.

I feel you want to know if malloc memory allocated in a method, return the pointer to main, and free the pointer in main will work or not ? Yes it can be done and free will clear the memory allocated in other methods provided you have the pointer pointing to that location.

Sunil Bojanapally
  • 12,528
  • 4
  • 33
  • 46
  • Yes, the second part was exactly, what i want to know. And in addition I know now, that i made a huge mistake, mixing the malloc with delete. – print x div 0 Feb 20 '14 at 09:35
  • @AndroidRookie Ok. In your example you need just the pointer to memory location allocated using `malloc` which can be free'd from other methods. – Sunil Bojanapally Feb 20 '14 at 09:38
2

No - thats undefined bahaviour which means it might look like it works but actually it does not, for malloc() you should always use free(). Use delete[] only for memory allocated with new[].

You can actually check it yourself, new[] calls void* operator new(size_t) method which should be somewhere declared in your platform headers. The easiest way is to spy on whay it does with debugger, under VS2005 it calls in the end HeapAlloc function.

For deallocation you have void operator delete[](void*) which also must be defined somwhere. On VS2005 it calls HeapFree.

I checked what malloc/free calls, and those are also HeapAlloc and HeapFree.

So in my case it looks like it would work, because malloc looks like its implemented in the same way as new[]. But the point is that there is no magic here, new[] should be paired with delete[], malloc() with free(), because you never know how those are implemented on given platform.

marcinj
  • 48,511
  • 9
  • 79
  • 100
1
  • When you dynamically allocate memory either using malloc or new, you are "reserving" a part of the heap memory for a particular purpose. The memory will remain "reserved" until you return it to the heap using free or delete (depending on what you used for allocation).
  • That being said, you can allocate memory from anywhere in the program and f*ree it from anywhere*. it's important however to be sure and do both if you forget to free the allocated memory you get memory leaks
Pandrei
  • 4,843
  • 3
  • 27
  • 44
0

Actually, you should use free with malloc, delete with new, but to me, it is not because of undefinedness, that it may blow a nuclear bomb, invoke nasal demons or whatever. (Or simply, maintenance nightmares) malloc and new don't do the same thing at all. To simplify what is actually a bit more complicated:

  • malloc, inherited from C, allocates a chunk of memory. Period.
  • new T allocates a correctly-sized chunk of memory intended to store an object of type T (possibly through malloc), and executes the object's constructor.

Conversely:

  • delete ptr executes the destructor of the object pointed-to by ptr and releases the related chunk of memory.
  • free(ptr) releases the chunk of memory. Period.

For the universe not to fall apart, every call to a constructor must match a call to the destructor. That's a guarantee of the language. (and one of the greatest strengths of C++)

That's why every call to malloc must match a call to free, because free was made to undo what malloc did. And every call to new must match a call to a delete because delete was made to undo what newdid.

Laurent LA RIZZA
  • 2,905
  • 1
  • 23
  • 41