When do I have to free memory? - c++

I learned C# and now I'm learning C++. The whole point of releasing a memory is new for me, and I want to know when I need to worry about memory releasing and when I don't.
From what I understand, the only case I have to worry about the release of memory, is when I used new operator, so I should to release the memory by using delete.
But in these cases there is no need to release the memory:
Class variables (Members), or static variables.
Local variables in function.
STL family (string, list, vector, etc.).
Is this true?
And are there other cases where I have to worry about memory releasing?

You basically got it right: You need to balance new with delete, new[] with delete[], and malloc with free.
Well-written C++ will contain almost none of those, since you leave the responsibiltiy for dynamic memo­ry and lifetime management to suitable container or manager classes, most notably std::vector and std::unique_ptr.

As a general rule of thumb I tend to abide by the following:
If I code a new/new[] i immediately code the corresponding delete/delete[]
Likewise any malloc/calloc is immediately followed by the relevant free
This avoids many nasty situations where you can generate a memory leak.
If you are new to C++ I would not get used to malloc and its many variants, it requires a lot of scaffolding to remain type-safe, which unless truly necessary can be counted as a bad thing, however, as mentioned, there are times it is necessary: for example, when having to use C-based libraries/APIs then you may conceivably need to use them.
In the main stay well clear of them and your life will be much easier.
Note: I mention the points above, as having gone from C to C++ I have had to face up to a lot of old tried and tested techniques from C which cause problems in C++.

Related

Should I delete pointers that come from other functions or class methods?

I have a background in Java and I'm still not fully used to the concept of pointers and scope, so sorry if the question seems silly.
I read somewhere that I should delete pointers that I have allocated on the Heap. I understand that but should I also delete a pointer that is given to me like this:
#include<dirent.h>
DIR* dir;
struct dirent* entries;
dir= opendir("D:/DIR")
entries= readdir(entries)
// Should I delete the pointers after I'm done with them?
delete entries;
delete dir;
Should I delete the pointers which are assigned from somewhere else or just going out of scope deletes them automatically?
Or is it even right to delete them since I haven't assigned them using new? But then if it's wrong how can I make sure that the memory assigned from the other methods would be deleted after I'm finished using them?
Not necessarily.
The unavoidable rule in C++ is that every new needs to be paired with a delete, and every new[] with a delete[], and that malloc, free, &c. are still available.
So it's tempting to suppose that the memory you get back from readdir is required to be released with an explicit call to delete, but that might not be the case:
It might have been allocated with a new[], or even, malloc!
The library might provide a function that you need to call that releases the memory.
If the library has a persuasion to working well with the C++ standard library, it might provide you with a deleter: which you can pass on construction to a smart pointer such as std::unique_ptr.
I think that (2) is most likely and is the most sensible since different C++ runtime environments might perform new and delete differently. (3) is an extension to this concept and if they support it then use that.
The golden rule is to check the documentation and do what it tells you.
There's no definitive answer to the question, because it always depends on the semantics by which the memory was allocated. For example in the very code example you gave, you must not use delete for deallocation, because opendir is not a C++ function (but a POSIX one) and to properly close it you call closedir. The pointer itself then can be discarded (no deletion requierd, closedir internally does the cleanup). Just make sure you don't use it after free (see: use-after-free-bug).
In general you always have to consult the manual of the function that gives you a pointer, where it's also specified exactly how to deallocate it.
Just to give you the idea:
malloc/calloc/realloc → free
fopen → fclose
X… → XFree
C is not the same as C++, notably for this aspect.
When using some external C (or C++) function provided by some external library, you should read its documentation and follow the "ownership" rules and conventions. For example if you use getline you understand that you need to free like here. If you use opendir you should use closedir. If you use sqlite3_prepare_v2 you'll need to sqlite3_finalize it, etc... Sometimes you'll think in terms of some abstract data type (like here) with a destructor-like function.
When you develop your own (public or "private") function in C, you need to document if it returns heap allocated memory and who (and how) is responsible of free (or releasing) it.
With C++, you also have smart pointers and RAII; so you generally can avoid manual new and delete. Smart pointers are helpful, but not a silver bullet.
So you should explicit and document conventions (and follow the conventions of external libraries and APIs) about ownership. Understanding and defining wisely such conventions is an important task.
Circular references are difficult to handle (consider weak pointers when applicable). I recommend reading about garbage collection concepts and techniques (e.g. the GC handbook), to at least be able to name appropriately your approaches and understand the limitations and power of reference counting. In some cases, you might even explicitly use a garbage collector library or code your own allocator.
Manual memory management is a whole program property, and that is why it is hard. There are even cases (long-living processes doing a lot of allocation) where you need to be afraid of fragmentation.
Tools like valgrind and the address sanitizer (with GCC's instrumentation options or Clang's ones) are practically very helpful to hunt memory leaks and some other memory bugs. Be also aware of ASLR. Take care to understand the virtual address space of your process. On Linux, read proc(5) then try cat /proc/$$/maps and cat /proc/self/maps in some terminal for a useful insight.
Ultimately you should consult the vendor's manual and see if their functions do the cleaning themselves or you need to call another function to do the cleaning etc. In general when talking about raw pointers in C++ you should explicitly release the allocated memory where appropriate. Whether it comes from a function or a new / new[] operator does not make a difference. To avoid this new / delete combination you can utilize smart pointers and the RAII technique.

Why use new and delete at all?

I'm new to C++ and I'm wondering why I should even bother using new and delete? It can cause problems (memory leaks) and I don't get why I shouldn't just initialize a variable without the new operator. Can someone explain it to me? It's hard to google that specific question.
For historical and efficiency reasons, C++ (and C) memory management is explicit and manual.
Sometimes, you might allocate on the call stack (e.g. by using VLAs or alloca(3)). However, that is not always possible, because
stack size is limited (depending on the platform, to a few kilobytes or a few megabytes).
memory need is not always FIFO or LIFO. It does happen that you need to allocate memory, which would be freed (or becomes useless) much later during execution, in particular because it might be the result of some function (and the caller - or its caller - would release that memory).
You definitely should read about garbage collection and dynamic memory allocation. In some languages (Java, Ocaml, Haskell, Lisp, ....) or systems, a GC is provided, and is in charge of releasing memory of useless (more precisely unreachable) data. Read also about weak references. Notice that most GCs need to scan the call stack for local pointers.
Notice that it is possible, but difficult, to have quite efficient garbage collectors (but usually not in C++). For some programs, Ocaml -with a generational copying GC- is faster than the equivalent C++ code -with explicit memory management.
Managing memory explicitly has the advantage (important in C++) that you don't pay for something you don't need. It has the inconvenience of putting more burden on the programmer.
In C or C++ you might sometimes consider using the Boehm's conservative garbage collector. With C++ you might sometimes need to use your own allocator, instead of the default std::allocator. Read also about smart pointers, reference counting, std::shared_ptr, std::unique_ptr, std::weak_ptr, and the RAII idiom, and the rule of three (in C++, becoming the rule of 5). The recent wisdom is to avoid explicit new and delete (e.g. by using standard containers and smart pointers).
Be aware that the most difficult situation in managing memory are arbitrary, perhaps circular, graphs (of reference).
On Linux and some other systems, valgrind is a useful tool to hunt memory leaks.
The alternative, allocating on the stack, will cause you trouble as stack sizes are often limited to Mb magnitudes and you'll get lots of value copies. You'll also have problems sharing stack-allocated data between function calls.
There are alternatives: using std::shared_ptr (C++11 onwards) will do the delete for you once the shared pointer is no longer being used. A technique referred to by the hideous acronym RAII is exploited by the shared pointer implementation. I mention it explicitly since most resource cleanup idioms are RAII-based. You can also make use of the comprehensive data structures available in the C++ Standard Template Library which eliminate the need to get your hands too dirty with explicit memory management.
But formally, every new must be balanced with a delete. Similarly for new[] and delete[].
Indeed in many cases new and delete are not needed, you can just use standard containers instead and leaving to them the allocation/deallocation management.
One of the reasons for which you may need to use allocation explicitly is for objects where the identity is important (i.e. they are not just values that can be copied around).
For example if you have a gui "window" object then making copies probably doesn't make sense and thus you're more or less ruling out all standard containers (they're designed for objects that can be copied and assigned). In this case if the object needs to survive the function that creates it probably the simplest solution is to just allocate explicitly it on the heap, possibly using a smart pointer to avoid leaks or use-after-delete.
In other cases it may be important to avoid copies not because they're illegal, but just not very efficient (big objects) and explicitly handling the instance lifetime may be a better (faster) solution.
Another case where explicit allocation/deallocation may be the best option are complex data structures that cannot be represented by the standard library (for example a tree in which each node is also part of a doubly-linked list).
Modern C++ styles often frown on explicit calls to new and delete outside of specialized resource management code.
This is not because the stack/automatic storage is sufficient, but rather because RAII smart resource owners (be they containers, shared pointers, or something else) make almost all direct memory wrangling unnessecary. And as the problem of memory management is often error prone, this makes your code more robust, easier to read, and sometimes faster (as the fancy resource owners can use techniques you might not bother with everywhere).
This is exemplified by the rule of zero: write no destructor, copy/move assign, copy/move constructor. Store state in smart storage, and have it handle it for you.
None of the above applies when you yourself are writing smart memory owning classes. This is a rare thing to need to do, however. It also requires C++14 (for make_unique) to get rid of the penultimate excuse to call new.
Now, the free store is still used, just not directly, under the above style. The free store (aka heap) is needed because automatic storage (aka the stack) only supports really simple object lifetime rules (scope based, compile time deterministic size and count, FILO order). As runtime sized and counted data is common, and object lifetime is often not that simple, the free store is used by most programs. Sometimes copying an object around on the stack is enough to make the simple lifetime less of a problem, but at other times identity is important.
The final reason is stack overflow. On some C++ implementations the stack/automatic storage is seriously constrained in size. What more is that there is rarely if ever a reliable failure mode when you put to much stuff in it. By storing large data on the free store, we can reduce the chance the stack will overflow.
First, if you don't need dynamic allocation, don't use it.
The most frequent reason for needing dynamic allocation is that
the object will have a lifetime which is determined by the
program logic rather than lexical scope. The new and
delete operators are designed to support explicitly managed
lifetimes.
Another common reason is that the size or structure of the
"object" is determined at runtime. For simple cases (arrays,
etc.) there are standard classes (std::vector) which will
handle this for you, but for more complicated structures (e.g.
graphs and trees), you'll have to do this yourself. (The usual
technique here is to create a class representing the graph or
tree, and have it manage the memory.)
And there is the case where the object must be polymorphic, and
the actual type won't be known until runtime. (There are some
tricky ways of handling this without dynamic allocation in the
simplest cases, but in general, you'll need dynamic allocation.)
In this case, std::unique_ptr might be appropriate to handle
the delete, or if the object must be shared, std::shared_ptr
(although usually, objects which must be shared fall into the
first category, above, and so smart pointers aren't
appropriate).
There are probably other reasons as well, but these are the
three that I've encountered the most often.
Only on simple programs you can know beforehand how much memory you'd use. In general you can not foresee how much memory you'd use.
However with modern C++11 you generally rely on standard libraries like vector and map for memory allocation, and the use of smart pointers helps you avoid memory leaks, so you don't really need to use new and delete explicitly by hand.
When you are using New then your object stores in Heap, and it remains there until you don't manually delete it. but in the case without using new your object goes in Stack and it destroys automatically when it goes out of scope.
Stack is set to a fix size, so if there is no any block for assign a new object then Stack Overflow occurs. This often happens when a lot of nested functions are being called, or if there is an infinite recursive call. If the current size of the heap is too small to accommodate new memory, then more memory can be added to the heap by the operating system.
Another reason may be if you are explicitly calling an external library or API with a C-style interface. Setting up a callback in such cases often means context data must be supplied and returned in the callback, and such an interface usually provides only a 'simple' void* or int*. Allocating an object or struct with new is appropriate for such actions, (you can delete it later in the callback, should you need to).

About the usage of new and delete, and Stroustrup's advice

About the usage of new and delete, and Stroustrup's advice...
He says something like (but not exactly, this is from my notes of his book):
A rule of thumb is that, new belongs in constructors and similar operations, delete belongs in destructors. In addition, new is often used in arguments to resource handles. Otherwise avoid using new and delete, use resource handles (smart pointers) instead.
I was wondering if the more experienced folks with C++11 have really applied this or not.
My impression of this was, wow this seems like a really cool rule to follow.
But then I got suspicious, as for any general rule. At the end of the day
you will end up using new and delete wherever necessary. But maybe this rule
is a good guideline I don't know.
It's a great rule. In fact, you can avoid using new in arguments to smart pointers by using the appropriate make_ functions. For example, instead of:
std::shared_ptr<int> p(new int(5));
You can often do:
auto p = std::make_shared<int>(5);
This also has the benefit of being more exception safe. While a std::make_unique doesn't yet exist, it is planned to make its way into C++14 (it is already in the working draft). If you want it now, there are some existing implementations.
You can go a step further and even avoid using new and delete in constructors and destructors. If you always wrap dynamically allocated objects in smart pointers, even when they're class members, you won't need to manage your own memory at all. See the Rule of Zero. The idea is that it's not the responsibility of your class to implement any form of ownership semantics (SRP) - that's what the smart pointers are for. Then you theoretically never have to write copy/move constructors, copy/move assignment operators or destructors, because the implicitly defined functions will generally do the appropriate thing.
Seems more like a poll than a question but here it goes: in application code I generally don't use new at all. Due to our coding guidelines the code does use pointer but none of these "naked" pointers is actually transfering ownership. All objects are owned by some other object.
To be fair, when objects need to be allocated the allocation generally uses something morally equivalent to std::make_shared<T>(...) which sometimes does show up in application code. One major reason for this rather thorough absence of new (or similar) is that objects are generally allocated using stateful allocators and not doing so via a resource manager actually happens to be fairly complicated. Thus, there is little place for direct memory allocation using new or a placement version thereof in application code.
In some infrastructure code, especially when creating custom containers the situation is slightly different: there is memory allocated (from allocators and initialized using placement new) there. However, even there any result from memory allocation and initialization of objects is immediately passed on to resource managers. Basically, I can't cope with explicit resource management and using resource managers just reliefs me of the necessary work.
The way I think of it is that every resource should be owned by something. The owner is the one who is responsible for cleaning up. Usually this owner is a smart pointer of some kind, but even std::vector is an owner a resource: the block of memory which stores it's contiguous elements. This advice holds not just for memory but any resource such as file descriptors, database handles, mutexes, etc...
When you call new and delete manually in some part of your code that's not a wrapper class, you the programmer become the resource owner. With ownership comes the responsibility of cleaning up after yourself. Now you and all of the maintenance programmers who come after you have to ensure that all code paths after the new eventually lead to a delete. Even for simple functions this very is easy to get wrong. With exceptions, almost impossible unless you carefully wrap everything in try catch blocks, resulting runtime performance penalties and polluting your code with extra scopes and unnecessary exception logic. Finally, even if you do get it right, you just wasted a lot your time doing this tedious work of resource management. The compiler is tool which can do this work for you, use it.
The worst situation is when some subsystem allocates a resource, it gets passed around the application, and some other far away subsystem frees it. The number of possible code paths in this situation is intractable. It is very difficult if not impossible for a human being to reason about and trust. In my opinion, this style of programming is unmaintainable. How many C projects have you worked with in the past that are riddled with memory errors, especially on rarely if never executed error handling paths? I've dealt with more than I care to see anymore.
C has manual memory management, Java and others have garbage collection. C++ has RAII. It's as efficient as C and and almost as safe as garbage collection.
My rule is simple, if you find yourself manually cleaning up any resource, you have just written a bug.

Is it secure to use malloc?

Somebody told me that allocating with malloc is not secure anymore, I'm not a C/C++ guru but I've made some stuff with malloc and C/C++. Does anyone know about what risks I'm into?
Quoting him:
[..] But indeed the weak point of C/C++ it is the security, and the Achilles' heel is indeed malloc and the abuse of pointers. C/C++ it is a well known insecure language. [..] There would be few apps in what I would not recommend to continue programming with C++."
It's probably true that C++'s new is safer than malloc(), but that doesn't automatically make malloc() more unsafe than it was before. Did your friend say why he considers it insecure?
However, here's a few things you should pay attention to:
1) With C++, you do need to be careful when you use malloc()/free() and new/delete side-by-side in the same program. This is possible and permissible, but everything that was allocated with malloc() must be freed with free(), and not with delete. Similarly, everything that was allocated with new must be freed with delete, and never with free(). (This logic goes even further: If you allocate an array with new[], you must free it with delete[], and not just with delete.) Always use corresponding counterparts for allocation and deallocation, per object.
int* ni = new int;
free(ni); // ERROR: don't do this!
delete ni; // OK
int* mi = (int*)malloc(sizeof(int));
delete mi; // ERROR!
free(mi); // OK
2) malloc() and new (speaking again of C++) don't do exactly the same thing. malloc() just gives you a chunk of memory to use; new will additionally call a contructor (if available). Similarly, delete will call a destructor (if available), while free() won't. This could lead to problems, such as incorrectly initialized objects (because the constructor wasn' called) or un-freed resources (because the destructor wasn't called).
3) C++'s new also takes care of allocating the right amount of memory for the type specified, while you need to calculate this yourself with malloc():
int *ni = new int;
int *mi = (int*)malloc(sizeof(int)); // required amount of memory must be
// explicitly specified!
// (in some situations, you can make this
// a little safer against code changes by
// writing sizeof(*mi) instead.)
Conclusion:
In C++, new/delete should be preferred over malloc()/free() where possible. (In C, new/delete is not available, so the choice would be obvious there.)
[...] C/C++ it is a well known insecure language. [...]
Actually, that's wrong. Actually, "C/C++" doesn't even exist. There's C, and there's C++. They share some (or, if you want, a lot of) syntax, but they are indeed very different languages.
One thing they differ in vastly is their way to manage dynamic memory. The C way is indeed using malloc()/free() and if you need dynamic memory there's very little else you can do but use them (or a few siblings of malloc()).
The C++ way is to not to (manually) deal with dynamic resources (of which memory is but one) at all. Resource management is handed to a few well-implemented and -tested classes, preferably from the standard library, and then done automatically. For example, instead of manually dealing with zero-terminated character buffers, there's std::string, instead of manually dealing with dynamically allocated arrays, there std:vector, instead of manually dealing with open files, there's the std::fstream family of streams etc.
Your friend could be talking about:
The safety of using pointers in general. For example in C++ if you're allocating an array of char with malloc, question why you aren't using a string or vector. Pointers aren't insecure, but code that's buggy due to incorrect use of pointers is.
Something about malloc in particular. Most OSes clear memory before first handing it to a process, for security reasons. Otherwise, sensitive data from one app, could be leaked to another app. On OSes that don't do that, you could argue that there's an insecurity related to malloc. It's really more related to free.
It's also possible your friend doesn't know what he's talking about. When someone says "X is insecure", my response is, "in what way?".
Maybe your friend is older, and isn't familiar with how things work now - I used to think C and C++ were effectively the same until I discovered many new things about the language that have come out in the last 10 years (most of my teachers were old-school Bell Laboratories guys who wrote primarily in C and had only a cursory knowledge of C++ - and Bell Laboratories engineers invented C++!). Don't laugh at him/her - you might be there someday too!
I think your friend is uncomfortable with the idea that you have to do your own memory management - ie, its easy to make mistakes. In that regard, it is insecure and he/she is correct... However, that insecure aspect can be overcome with good programming practices, like RAII and using smart pointers.
For many applications, though, having automated garbage collection is probably fine, and some programmers are confused about how pointers work, so as far as getting new, inexperienced developers to program effectively in C/C++ without some training might be difficult. Which is maybe why your friend thinks C/C++ should be avoided.
It's the only way to allocate and deallocate memory in C natively. If you misuse it, it can be as insecure as anything else. Microsoft provides some "secure" versions of other functions, that take an extra size_t parametre - maybe your friend was referring to something similar? If that's the case, perhaps he simply prefers calloc() over malloc()?
If you are using C, you have to use malloc to allocate memory, unless you have a third-party library that will allocate / manage your memory for you.
Certainly your friend has a point that it is difficult to write secure code in C, especially when you are allocating memory and dealing with buffers. But we all know that, right? :)
What he maybe wanted to warn you is about pointers usage. Yes, that will cause problems if you don't understand how it works. Otherwise, ask what your friend meant, or ask him for a reference that proof his affirmation.
Saying that malloc is not safe is like saying "don't use system X because it's insecure".
Until that, use malloc in C, and new in C++.
If you use malloc in C++, people will look mad at you, but that's fine in very specific occasions.
There is nothing wrong with malloc as such. Your friend apparently means that manual memory management is insecure and easily leads to bugs. Compared to other languages where the memory is managed automatically by a garbage collector (not that it is not possible to have leaks - nowadays nobody cares if the program cleans up when it terminates, what matters is that something is not hogging memory while the program is running).
Of course in C++ you wouldn't really touch malloc at all (because it simply isn't functionally equivalent to new and just doesn't do what you need, assuming most of the time you don't want just to get raw memory). And in addition, it is completely possible to program using techniques which almost entirely eliminate the possibility of memory leaks and corruption (RAII), but that takes expertise.
Technically speaking, malloc was never secure to begin with, but that aside, the only thing I can think of is the infamous "OOM killer" (OOM = out-of-memory) that the Linux kernel uses. You can read up on it if you want. Other than that, I don't see how malloc itself is inherently insecure.
In C++, there is no such problem if you stick to good conventions. In C, well, practice. Malloc itself is not an inherently insecure function at all - people simply can deal with it's results inadequately.
It is not secure to use malloc because it's not possible to write a large scale application and ensure every malloc is freed in an efficient manner. Thus, you will have tons of memory leaks which may or may not be a problem... but, when you double free, or use the wrong delete etc, undefined behaviour can result. Indeed, using the wrong delete in C++ will typically allow arbitrary code execution.
The ONLY way for code written in a language like C or C++ to be secure is to mathematically prove the entire program with its dependencies factored in.
Modern memory-safe languages are safe from these types of bugs as long as the underlying language implementation isn't vulnerable (which is indeed rare because these are all written in C/C++, but as we move towards hardware JVMs, this problem will go away).
Perhaps the person was referring to the possibility of accessing data via malloc()?
Malloc doesn't affect the contents of the region that it provides, so it MAY be possible to collect data from other processes by mallocing a large area and then scanning the contents.
free() doesn't clear memory either so data paced into dynamically allocated buffers is, in principle, accessible.
I know someone who, many years ago admittedly, exploited malloc to create an inter-process communication scheme when he found that mallocs of equal size would return the address of the most recently free'd block.

How to prevent inadvertently using delete and free interchangeably in C++?

When, if ever, can delete and free be used interchangeably in C++?
My concern is as follows: Say there is an incorrect mixup in the use of malloc/ free and
new/ delete (not to mention new[]/ delete[]). However delete and free doing the same thing;
Fortuitously so this goes uncaught in testing. Later this may lead to a crash in production.
How can I enforce some kind of check to prevent this? Can I be warned if the two are mixed up?
If not at compile time, perhaps some code instrumentation at run time? How would I approach
this?
The intention of this question is to find ways to avoid inadvertent mix up in the usages.
The easy way to not get them mixed up is never to use malloc(), then you will never be tempted to call free(). The infrastructure to create to avoid this problem is called "code review", though in this case a quick "grep malloc(" or "grep free(" on the codebase will probably suffice.
Never. If it works it's by sheer accident of implementation. Do not rely on this behavior.
To answer the second question, if you control both malloc/free and operator new/delete, you can stash extra information to associate with pointers returned by both that tell you how they were allocated. When a pointer is passed to free or operator delete, check to see that it was allocated by the appropriate function. If not, assert or raise an exception or do whatever it is you do to report the mismatch.
Usually this is done by allocating extra memory, e.g., given malloc(size) or operator new(size), you allocate size + additional space and shove extra information in there.
The only way you can ensure you never get them mixed up is by either:
Never using malloc/free in the first place, or
Rely on RAII for your memory allocations. Protect every memory allocation in a RAII object which ensures the memory get correctly and consistently freed when it goes out of scope, or wrap the allocation in a smart pointer.
Manually calling delete or free is just an invitation for bugs.
You should always use new and delete in C++, as only new and delete will call the object's constructor and destructor.
If you find you must use both (for instance, if you're interfacing with a C library), thorough code reviews should carefully scrutinize any uses of free() to determine whether or not they correspond to a malloc(), and whether or not they are being used in a C context.
If I had to codify it, I'd put in the style guide something like this:
free() may be called only on a private pointer field of an object.
malloc()ed buffers (or buffers returned from a C API which caller must free()) must be assigned to a private pointer field of an object.
private pointer fields which hold free()-able buffers must only be used for that purpose.
if you use hungarian notation, add a letter for it (and if you don't, don't).
generally free() will be called only in a destructor, with exceptions when the free()-able buffer is replaced during the lifetime of the object. In that case you can call free() on a value recently copied out of a private field during replacement, rather than on the field value directly.
In other words, stick a wrapper around anything that uses malloc/free. This wrapper could be a single template everyone uses, or you could allow smart pointers with the deletor function set to free(). Then in code review, if you see a call to malloc/free anywhere else, it's wrong.
Basically the best way to stop this being a problem is to be on top of your resource handling in general. In C, people do not have a major problem with accidentally calling free() on streams instead of fclose().
You should always use delete or delete[] when freeing things allocated with new. The same goes for malloc and free.
If using free for deleting new:ed classes the destructor won't be properly called.
Also new and delete doesn't necessarily use malloc/free for its allocations so you might end up corrupting your heap as well.
always use delete for things allocated with new, delete [] for things allocated with new [] and free() for things allocated using malloc().
new and new[] allocate from different heaps than malloc() and using the wrong free()/delete will attempt to deallocate from the wrong heap.
Never mix new/delete with new[]/delete[] or with malloc()/free(). Atop of this, the use of malloc()/free() in C++ is questionable at least.
The easiest way to make sure you never do this accidentally is to not to manage memory manually. In C++ there strings and other containers as well as smart pointers to take care of memory management. There simply isn't a need to do this manually. (I'm not sure whether the last time I remember me typing delete really was the last time I typed it. But if my memory doesn't fail me, this must have been 2001 or 2002.)
You could write your own version of the functions which allocate some extra memory in new/new[]/malloc to track which one did the allocation. Then check in delete/delete[]/free that the right function was used to re-claim the memory. You can also check for things like mixing new[] and delete (without the []) this way. You might want to only use these versions in the debug build.
You could try running valgrind on your application to see if it catches anything. The manual specifically mentions its ability to catch uses of the wrong deallocation function for a block of memory. I don't think there's a way to do this at compile time, however.
One way to avoid misusage of malloc/free or new/delete is that DO NOT call these function directly, call them by a wrapper layer. In the wrapper layer, you can manage the pointers distributed by your own hands and guarantee that misusage will get an error explicitly.
Why dont you just count the total number of malloc statments and tally that with the total count of free? Do the same for New and delete. The process can be automated with regular expressions.
One thing I've done relating to this is to reimplement malloc and free
in C++, so that it calls new/delete under the hood. It's not
optimal, but it serves well enough on a smaller project.