This question already has answers here:
Closed 13 years ago.
I think we all understand the necessity of delete when reassigning a dynamically-allocated pointer in order to prevent memory leaks. However, I'm curious, to what extent does the C++ mandate the usage of delete? For example, take the following program
int main()
{
int* arr = new int[5];
return 0;
}
While for all intents and purposes no leak occurs here (since your program is ending and the OS will clean up all memory once it returns), but does the standard still require -- or recommend -- the usage of delete[] in this case? If not, would there be any other reason why you would delete[] here?
There is nothing that requires a delete[] in the standard - However, I would say it is a very good guideline to follow.
However, it is better practice to use a delete or delete[] with every new or new[] operation, even if the memory will be cleaned up by the program termination.
Many custom objects will have a destructor that does other logic than just cleaning up the memory. Using delete guarantees the destruction in these cases.
Also, if you ever move around your routines, you are less likely to cause memory leaks in other places in your code.
Dupe of Is there a reason to call delete in C++ when a program is exiting anyway?
Answer is that because of destructors that need to be run, it is sometimes necessary to delete the object before exiting the program. Also, many memory leak detection tools will complain if you don't do this, so to make it easier to find real memory leaks, you should try and delete all of your objects before exiting.
Please see:
When to use "new" and when not to, in C++?
About constructors/destructors and new/delete operators in C++ for custom objects
delete and delete [] the same in Visual C++?
Why is there a special new and delete for arrays?
How to track memory allocations in C++ (especially new/delete)
Array of structs and new / delete
What is the difference between new/delete and malloc/free?
Here no. But as the program gets larger and more complex I would manage my memory so that I can track down bugs faster. The standard says nothing but getting into good habits in the smaller case leads to better code long term.
You are perfectly free to forget to delete things.
Do you like wasting memory?
I don't know the Standard, but there is a whole programming style around this question: crash-only softxare
Theoretically databases or OS kernels should be developed as such, but often it's not really practical to use them like that because on restart there is some cleanup that can be long. Moreover dependent systems (programs inside an OS or database clients) might not be crash-only.
Related
I have read this question and answer
dynamically allocated memory after program termination,
and I want to know if it is okay to NOT delete dynamically allocated memory and let it get freed by the OS after programme termination.
So, if I have allocated some memory for objects that I need thoughout the programme, is it ok to skip deleting them at the end of the programme, in order to make the code run faster?
The short answer is yes, you can, the long answer is possibly you better not do that: if your code needs to be refactored and turned into a library, you are delivering a considerable amount of technical debt to the person who is going to do that job, which could be you.
Furthermore, if you have a real, hard-to-find memory leak (not a memory leak caused by you intentionally not freeing long-living objects) it's going to be quite time consuming to debug it with valgrind due to a considerable amount of noise and false positives.
Have a look at std::shared_ptr and std::unique_ptr. The latter has no overhead.
Most sane OS release all memory and local resources own by the process upon termination (the OS may do it in lazy manner, or reduce their share counter, but it does not matter much on the question). So, it is safe to skip releasing those resources.
However, it is very bad habit, and you gain almost nothing. If you found releasing object takes long time (like walking in a very long list of objects), you should refine your code and choose a better algorithm.
Also, although the OS will release all local resources, there are exceptions like shared memory and global space semaphore, which you are required to release them explicitly.
First of all, the number one rule in C++ is:
Avoid dynamic allocation unless you really need it!
Don't use new lightly; not even if it's safely wrapped in std::make_unique or std::make_shared. The standard way to create an instance of a type in C++ is:
T t;
In C++, you need dynamic allocation only if an object should outlive the scope in which it was originally created.
If and only if you need to dynamically allocate an object, consider using std::shared_ptr or std::unique_ptr. Those will deallocate automatically when the object is no longer needed.
Second,
is it ok to skip deleting them at the end of the programme, in order
to make the code run faster?
Absolutely not, because of the "in order to make the code run faster" part. This would be premature optimisation.
Those are the basic points.
However, you still have to consider what constitutes a "real", or bad memory leak.
Here is a bad memory leak:
#include <iostream>
int main()
{
int count;
std::cin >> count;
for (int i = 0; i < count; ++i)
{
int* memory = new int[100];
}
}
This is not bad because the memory is "lost forever"; any remotely modern operating system will clean everything up for you once the process has gone (see Kerrek SB's answer in your linked question).
It is bad because memory consumption is not constant when it could be; it will unnecessarily grow with user input.
Here is another bad memory leak:
void OnButtonClicked()
{
std::string* s = new std::string("my"); // evil!
label->SetText(*s + " label");
}
This piece of (imaginary and slightly contrived) code will make memory consumption grow with every button click. The longer the program runs, the more memory it will take.
Now compare this with:
int main()
{
int* memory = new memory[100];
}
In this case, memory consumption is constant; it does not depend on user input and will not become bigger the longer the program runs. While stupid for such a tiny test program, there are situations in C++ where deliberately not deallocating makes sense.
Singleton comes to mind. A very good way to implement Singleton in C++ is to create the instance dynamically and never delete it; this avoids all order-of-destruction issues (e.g. SettingsManager writing to Log in its destructor when Log was already destroyed). When the operating system clears the memory, no more code is executed and you are safe.
Chances are that you will never run into a situation where it's a good idea to avoid deallocation. But be wary of "always" and "never" rules in software engineering, especially in C++. Good memory management is much harder than matching every new with a delete.
Short story . . . I am trying to override new and delete operators. Seem to be okay on new but on delete I have a problem with this bit of code
cCellList::~cCellList()
{
STPINT loop;
for (loop = 0; loop < count; loop++)
{
delete cells[loop];
}
free(cells);
}
The delete here is not going to my overridden delete operator, so things are not working out. The stack trace says
ExeName.exe!Cell::'scalar deleting destructor'()
ExeName.exe!cCellList::~cCellList()
ExeName.exe!Cell::'scalar deleting destructor'()
The line of code being executed is
delete cells
where cells is of type cCellList *.
Long story. I have been working on this executable for nearly 20 years, part time, and it has about 14 MB of source code. All unmanaged C++, currently using VS2010. I started out with a compiler named "Think C with Object-oriented extensions". Probably many of you are too young to remember those days.
Someplace in there is a memory management problem which causes strange things to happen sometimes. I have long since passed the point where third-party solutions like Purify can be used on this program. They just bomb when I try to instrument the code. So I have written my own malloc/free and I am hooking these up to keep better track of what is happening to the memory. So far, I am allocating all the memory with my own system, but in this case it is going to the normal "free" instead of mine, with predictable results.
free(cells);
Did you allocate the memory with malloc?
If yes, don't do that. Classes do not play nice with malloc. new exists for a reason. There are all kinds of things that can go wrong here.
If no, then don't deallocate it with free. That is undefined behaviour. If you wrote cells = new Cell[n] to allocate, you must use delete[] cells to deallocate. free may NOT be substituted for delete or delete[], and delete may NOT be substituted for delete[], or vice versa in any combination, no matter how much it "seems to work" or who told you it's ok. It is not ok.
What is the declaration of the delete operator?
As a general remark, your overridden malloc()/free() should take the form of overridden global new()/delete() operators, not forgetting to provide the vector versions. Similarly this destructor should call delete[] cells; instead of free(cells), assuming 'cells' was initialized via new cells[X], which it must have been, otherwise nothing would work, and specifically virtual methods.
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.
I heard that Python has automated "garbage collection" , but C++ does not. What does that mean?
Try reading up on it.
That means that python user doesn't need to clean his dynamic created objects, like you're obligated to do it in C/C++.
Example in C++:
char *ch = new char[100];
ch[0]='a';
ch[1]='b';
//....
// somewhere else in your program you need to release the alocated memory.
delete [] ch;
// use *delete ch;* if you've initialized *ch with new char;
in python:
def fun():
a=[1, 2] #dynamic allocation
a.append(3)
return a[0]
python takes care about "a" object by itself.
From Wikipedia http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29:
...
Garbage collection frees the programmer from manually dealing with memory allocation and deallocation. As a result, certain categories of bugs are eliminated or substantially reduced:
Dangling pointer bugs, which occur
when a piece of memory is freed while
there are still pointers to it, and
one of those pointers is used.
Double free bugs, which occur when
the program attempts to free a
region of memory that is already
free.
Certain kinds of memory leaks, in
which a program fails to free
memory that is no longer referenced
by any variable, leading, over time,
to memory exhaustion.
...
The basic principles of garbage collection are:
Find data objects in a program that cannot be accessed in the future
Reclaim the resources used by those objects
Others already answered the main question, but I'd like to add that garbage collection is possible in C++. It's not that automatic like Python's, but it's doable.
Smart pointers are probably the simplest form of C++ garbage collecting - std::auto_ptr, boost::scoped_ptr, boost::scoped_array that release memory after being destroyed. There's an example in one of the earlier answers, that could be rewritten as:
boost::scoped_array<char> ch(new char[100]);
ch[0] = 'a';
ch[1] = 'b';
// ...
// boost::scoped_array will be destroyed when out of scope, or during unwind
// (i.e. when exception is thrown), releasing the array's memory
There are also boost::shared_ptr, boost::shared_array that implement reference counting (like Python). And there are full-blown garbage collectors that are meant to replace standard memory allocators, e.g. Boehm gc.
It basically means the way they handle memory resources. When you need memory you usually ask for it to the OS and then return it back.
With python you don't need to worry about returning it, with C++ you need to track what you asked and return it back, one is easier, the other performant, you choose your tool.
As you have got your answer, now it's better to know the cons of automated garbage collection:
it requires large amounts of extra memory and not suitable for hard real-time deadline applications.
This question already has answers here:
Closed 13 years ago.
Duplicate of: In what cases do I use malloc vs new?
Just re-reading this question:
What is the difference between "new" and "malloc" and "calloc" in C++?
I checked the answers but nobody answered the question:
When would I use malloc instead of new?
There are a couple of reasons (I can think of two).
Let the best float to the top.
A couple that spring to mind:
When you need code to be portable between C++ and C.
When you are allocating memory in a library that may be called from C, and the C code has to free the allocation.
From the Stroustrup FAQ on new/malloc I posted on that thread:
Whenever you use malloc() you must consider initialization and convertion of the return pointer to a proper type. You will also have to consider if you got the number of bytes right for your use. There is no performance difference between malloc() and new when you take initialization into account.
This should answer your question.
The best reason I can think of to use malloc in C++ is when interacting with a pure C API. Some C APIs I've worked with take ownership of the memory of certain parameters. As such they are responsible for freeing the memory and hence the memory must be free-able via free. Malloc will work for this puprose but not necessarily new.
In C++, just about never. new is usually a wrapper around malloc that calls constructors (if applicable.)
However, at least with Visual C++ 2005 or better, using malloc can actually result in security vulnerabilities over new.
Consider this code:
MyStruct* p = new MyStruct[count];
MyStruct* p = (MyStruct*)malloc(count* sizeof(MyStruct));
They look equivelent. However, the codegen for the first actually checks for an integer overflow in count * sizeof(MyStruct). If count comes from an unstrusted source, it can cause an integer overflow resulting in a small amount of memory being allocated, but then when you use count you overrun the buffer.
Everybody has mentioned (using slightly different words) when using a C library that is going to use free() and there are a lot of those around.
The other situation I see is:
When witting your own memory management (because for some reason that you have discovered through modeling the default is not good enough). You could allocate memory block with malloc and the initialization the objects within the pools using placement new.
One of the reason is that in C++, you can overload the new operator.
If you wanted to be sure to use the system library memory allocation in your code, you could use malloc.
A C++ programmer should rarely if ever need to call malloc. The only reason to do so that I can think of would be a poorly constructed API which expected you to pass in malloc'd memory because it would be doing the free. In your own code, new should always be the equal of malloc.
If the memory is to be released by free() (in your or someone elses code), it's pretty darn required to use malloc.
Otherwise I'm not sure. One contrived case is when you don't want destructor(s) to be run on exit, but in that case you should probably have objects that have a no-op dtor anyway.
You can use malloc when you don't want to have to worry about catching exceptions (or use a non-throwing version of new).