I'm trying to gain some memory saving in a C++ program and I want to know if I can use blocks as a scope for variables (as in Perl). Let's say I have a huge object that performs some computations and gives a result, does it makes sense to do:
InputType input;
ResultType result;
{
// Block of code
MyHugeObject mho;
result = mho.superHeavyProcessing();
}
/*
My other code ...
*/
Can I expect the object to be destroyed when exiting the block?
Yes, you can.
The destructor will be called as soon as the variable falls out of scope and it should release the heap-allocated memory.
Yes absolutely, and in addition to conserving memory, calling the destructor on scope exit is often used where you want the destructor to actually do something when the destructor is called (see RAII). For example, to create a scope based lock and release easily it in an exception safe way, or to let go of access to a shared or precious resource (like a file handle / database connection) deterministically.
-Rick
Just remember that any memory you allocate on the heap using new/malloc that is freed in the destructor probably won't be released back to the OS. Your process may hold onto it and the OS won't get it back until the process terminates.
Yes. It will be destroyed at the closing curly brace. But beware of allocating very large objects on the stack. This can causes a stack overflow. If you object also allocates large amounts memory, make sure it is heap allocated with new, malloc, or similar.
Related
When using dynamically allocated objects in C++ eg:
TGraph* A = new TGraph(...);
One should always delete these because otherwise the objects might still be in memory when
control is handed back to the parent scope. While I can see why this is true for subscopes and subroutines of a program, does the same count for the main scope?
Am I obliged to delete objects that were dynamically built inside main()? The reason why this seems a bit redudant to me is that when main ends, the program also ends, so there is no need to worry about memory leaks.
Most of the modern OS always reclaim back all memory they allocated to a program(process).
The OS doesn't really understand if your program leaked memory it merely takes back what it allocatted.
But there are bigger issues at hand than just the memory loss:
Note that if the destructor of the object whos delete needs to be called performs some non-trivial operation and your program depends on the side effects produced by it then your program falls prey to Undefined Behavior[Ref 1]. Once that happens all bets are off and your program may show any beahvior.
Also, An OS usually reclaims the allocated memory but not the other resources, So you might leak those resources indirectly. This may include operations dealing with file descriptors or state of the program itself etc.
Hence, it is a good practice to always deallocate all your allocations by calling delete or delete [] before exiting your program.
[Ref 1]C++03 Standard 3.8 Para 4:
"....if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior."
IMO it is best to always call delete properly:
to make it an automatic habit, making it less likely to forget it when it is really needed
to cover cases when non-memory resources (sockets, file handles, ...) need to be freed - these aren't automatically freed by the OS
to cater for future refactoring when the code in question might be moved out of main scope
Yes, you should call delete, at least because it's best practice. If you have important logic in your destructor, that's one extra reason that you should call delete.
Corrected: If the program depends on logic in the destructor, not calling delete explicitly results in undefined behavior.
The reason why this seems a bit redudant to me is that when main ends,
the program also ends, so there is no need to worry about memory
leaks.
You're right, but consider this: you create a class object which opens a connection to remote DB. After your program will complete, you should tell the DB "I'm done, i'm going to disconnect", but it won't happen in the case you won't call delete properly.
Its the best practice to de-allocate memory that's been allocated. You should keep in mind that Heap memory is limited and just allocating with out de-allocating while your program is running might run the heap space out for some other/or the same program(if its some kind of a daemon that is meant to run for a very long time) that needs heap.
Of course memory will be reclaimed by the operating system at the end of the program's execution.
I see you are using ROOT (CMS guy?). I think ROOT takes care of this and cleans up, doesn't it?
Best practices:
Do not use new, use automatic allocation
When dynamic allocation is necessary, use RAII to ensure automatic cleanup
You should never have to write delete in applicative code.
Here, why are you calling new for TGraph ?
TGraph A(...);
works better: less worries!
I know that stack allocated resources are released in reverse order as they were allocated at the end of a function as part of RAII. I've been working on a project and I allocate a lot of memory with "new" from a library I'm using, and am testing stuff out. I haven't added a shutdown function as a counterpart to the initialise function that does all the dynamic allocation. When you shut down the program I'm pretty sure there is no memory leak as the allocated memory should be reclaimed by the operating system. At least any modern OS, as explained in this question similar to mine: dynamically allocated memory after program termination .
I'm wondering two things:
1: Is there a particular order that resources are released in in this case? Does it have anything to do with your written code (ie., which order you allocated it), or is it completely up to the OS to do its thing?
2: The reason I haven't made a shutdown function to reverse the initialisation is because I say to myself I'm just testing stuff now, I'll do it later. Is there any risk of doing any damage to anything by doing what I'm doing? The worse I can imagine is what was mentioned in the answer to that question I linked, and that is that the OS fails to reclaim the memory and you end up with a memory leak even after the program exits.
I've followed the Bullet physics library tutorial and initialise a bunch of code like this:
pSolver = new btSequentialImpulseConstraintSolver;
pOverlappingPairCache = new btDbvtBroadphase();
pCollisionConfig = new btDefaultCollisionConfiguration();
pDispatcher = new btCollisionDispatcher(pCollisionConfig);
pDynamicsWorld = new btDiscreteDynamicsWorld(pDispatcher, pOverlappingPairCache, pSolver, pCollisionConfig);
And never call delete on any of it at the moment because, as I said, I'm just testing.
It depends on the resources. Open files will be closed. Memory will be freed. Destructors will not be called. Temporary files created will not be deleted.
There is no risk of having a memory leak after the program exits.
Because programs can crash, there are many mechanisms in place preventing a process to leak after it stopped and leaking usually isn't that bad.
As a matter of fact, if you have a lot of allocations that you don't delete until the end of the program, it can be faster to just have the kernel clean up after you.
However destructors are not run. This mostly causes temporary files to not be deleted.
Also it makes debugging actual memory leaks more difficult.
I suggest using std::unique_ptr<T> and not leaking in the first place.
It depends on how the memory is actually allocated and on your host system.
If you are only working with classes that don't override operator new() AND you are using a modern operating system that guarantees memory resources are released when the process exits, then all dynamically allocated memory should be released when your program terminates. There is no guarantee on the order of memory release (e.g. objects will not be released in the same order, or in reverse order, of their construction). The only real risk in this case is associated with bugs in the host operating system that cause resources of programs/processes to be improperly managed (which is a low risk - but not zero risk - for user programs in modern windows or unix OSs).
If you are using any classes that override operator new() (i.e. that change how raw memory is allocated in the process of dynamically constructing an object) then the risk depends on how memory is actually being allocated - and what the requirements are for deallocation. For example, if the operator new() uses global or system-wide resources (e.g. mutexes, semaphores, memory that is shared between processes) then there is a risk that your program will not properly release those resources, and then indirectly cause problems for other programs which use the same resources. In practice, depending on the design of such a class, the needed cleanup might be in a destructor, an operator delete() or some combination of the two - but, however it is done, your program will need to explicitly release such objects (e.g. a delete expression that corresponds to the new expression) to ensure the global resources are properly released.
One risk is that destructors of your dynamically allocated objects will not be invoked. If your program relies on the destructor doing anything other than release dynamically allocated memory (presumably allocated by the class constructor and managed by other member functions) then the additional clean-up actions will not be performed.
If your program will ever be built and run on a host system that doesn't have a modern OS then there is no guarantee that dynamically allocated memory will be reclaimed.
If code in your program will ever be reused in a larger long-running program (e.g. your main() function is renamed, and then called from another program in a loop) then your code may cause that larger program to have a memory leak.
It's fine, since the operating system (unless it's some exotic or ancient OS) will not leak the memory after the process has ended. Same goes for sockets and file handles; they will be closed at process exit. It's not in good style to not clean up after yourself, but if you don't, there's no harm done to the overall OS environment.
However, in your example, it looks to me like the only memory that you would actually need to release yourself is that of pDynamicsWorld, since the others should be cleaned up by the btDiscreteDynamicsWorld instance. You're passing them as constructor arguments, and I suspect they get destroyed automatically when pDynamicsWorld gets destroyed. You should read the documentation to make sure.
However, it's just not in good style (because it's unsafe) to use delete anymore. So instead of using delete to destroy pDynamicsWorld, you can use a unique_ptr instead, which you can safely create using the std::make_unique function template:
#include <memory>
// ...
// Allocate everything else with 'new' here, as usual.
// ...
// Except for this one, which doesn't seem to be passed to another
// constructor.
auto pDynamicsWorld = std::make_unique<btDiscreteDynamicsWorld>(
pDispatcher, pOverlappingPairCache, pSolver, pCollisionConfig);
Now, pDispatcher, pOverlappingPairCache, pSolver and pCollisionConfig should be destroyed by pDynamicsWorld automatically, and pDynamicsWorld itself will be destroyed automatically when it goes out of scope because it's a unique_ptr.
But, again: Read the documentation of Bullet Physics to check whether the objects you pass as arguments to the constructors of the Bullet Physics classes actually do get cleaned up automatically or not.
It is said that the memory allocated by new should be freed by delete, but a modern desktop OS will reclaim the memory even though you don't delete it. So why should we delete the memory allocated by new?
Also assert is known as not calling the destructors, and it seems like it's widely used in STL (at least VS2015 does that). If it's advised to delete the memory allocated by new (classes like string, map and vector use the destructor to delete the allocated memory), why the developers still use lots of assert then?
Why should we delete the memory allocated by new?
Because otherwise
the memory is leaked. Not leaking memory is absolutely crucial for long running software such as servers and daemons because the leaks will accumulate and consume all available memory.
the destructors of the objects will not be called. The logic of the program may depend on the destructors being called. Not calling some destructors may cause non-memory resources being leaked as well.
Also assert is known as not calling the destructors
A failed assert terminates the entire process, so it doesn't really matter much whether the logic of the program remains consistent, nor whether memory or other resources are leaked since the process isn't going to reuse those resources anyway.
and it seems like it's widely used in STL (at least VS2015 does that)
To be accurate, I don't think the standard library is specified to use the assert macro. The only situation where it could use it is if you have undefined behaviour. And if you have UB, then leaked memory is the least of your worries.
If you know that the destructor of the object is trivial, and you know that the object is used throughout the program (so, it's essentially a singleton), then it's quite safe to leak the object on purpose. This does have a drawback that it will be detected by a memory leak sanitizer that you would probably want to use to detect accidental memory leaks.
It is said that the memory allocated by new should be freed by
delete, but a modern desktop OS will reclaim the memory even though
you don't delete it. So why should we delete the memory allocated
by new?
Careful! The OS reclaims the memory only after your program has finished. This is not like garbage collection in Java or C#, which frees memory while the program is running.
If you don't delete (or more precisely, if you don't make sure that delete is called by resource-managing classes like std::unique_ptr, std::string or std::vector), then memory usage will continue to grow until you run out of memory.
Not to mention that destructors will not run, which matters if you have objects of types whose destructors perform more than just releasing memory.
Also assert is known as not calling the destructors,
More precisely, assert causes the program to terminate in a way that destructors are not called, unless the corresponding translation unit was compiled with the NDEBUG preprocessor macro defined, in which case the assert does nothing.
and it seems like it's widely used in STL (at least VS2015 does that).
Yes, the standard-library implementation of Visual C++ 2015 does that a lot. You should also use it liberally in your own code to detect bugs.
The C++ standard itself does not specify how and if asserts should appear in the implementation of a standard-library function. It does specify situations where the behaviour of the program is undefined; those often correspond to an assert in the library implementation (which makes sense, because if the behaviour is undefined anyway, then the implementation is free to do anything, so why not use that liberty in a useful way to give you bug detection?).
If it's advised to delete the memory allocated by new (classes like
string, map and vector use the destructor to delete the allocated
memory), why the developers still use lots of assert then?
Because if an assertion fails, then you want your program to terminate immediately because you have detected a bug. If you have detected a bug, then your program is by definition in an unknown state. Allowing your program to continue in an unknown state by running destructors is possibly dangerous and may compromise system integrity and data consistency.
After all, as I said above, destructors may not only call delete a few times. Destructors close files, flush buffers, write into logs, close network connections, clear the screen, join on a thread or commit or rollback database transactions. Destructors can do a lot of things which can modify and possibly corrupt system resources.
It is a common pattern that applications - in the course of their execution -dynamically create objects that will not be used throughout the program execution. If an application creates a lot of such objects of temporary lifetime, it somehow has to manage memory in order not to run out of it. Note that memory is still limited, since operating systems usually do not assign all available memory to an application. Operating systems, especially those driving limited devices like mobile phones, may even kill applications once the produce a too high pressure on memory.
Hence, you should free the memory of those objects that are not used any more. And C++ offers storage class specifiers to make this handling easier. automatic storage duration, which is the default, deletes objects once they run out of scope (i.e. their enclosing block, e.g. the function in which they are defined, finishes). static objects remain until the end of normal program execution (if reached), and dynamically allocated objects remain until you call delete.
Note that - in no way - any object will survive the end of program execution, as the operating system will free the complete application memory. For normal program terminations, destructors of static objects will be called (but not for objects of dynamically created objects that have not been deleted before). For abnormal program terminations, like triggered by assert, exit or the operating system, no destructors are called; you can rather think of a program terminates because you turn off the power.
If you don't delete You introduce a memory leak. Each time this operator is invoked the process will waste some portion of its address space until it ultimately runs out of memory.
After your program finishes you do not need to care about memory leaks, so in principle this would be fine:
int main(){
int* x = new int(1);
}
However, thats not how one usually uses memory. Often you need to allocate memory for something that you use only for a short time and then you want to free that memory when you dont need it anymore. Consider this example:
int main(){
while ( someCondition ) {
Foo* x = new Foo();
doSomething(*x);
} // <- already here we do not need x anymore
}
That code will accumulate more and more memory for x even if all that is used is a single instance of x. Thats why one should free memory latest at the end of the scope where it is needed (once you left the scope you have no way to free it!). Because forgetting a delete isnt nice, one should make use of RAII whenever possible:
int main(){
while ( someCondition ) {
Foo x;
doSomething(x);
} // <- memory for x is freed automatically
}
When using dynamically allocated objects in C++ eg:
TGraph* A = new TGraph(...);
One should always delete these because otherwise the objects might still be in memory when
control is handed back to the parent scope. While I can see why this is true for subscopes and subroutines of a program, does the same count for the main scope?
Am I obliged to delete objects that were dynamically built inside main()? The reason why this seems a bit redudant to me is that when main ends, the program also ends, so there is no need to worry about memory leaks.
Most of the modern OS always reclaim back all memory they allocated to a program(process).
The OS doesn't really understand if your program leaked memory it merely takes back what it allocatted.
But there are bigger issues at hand than just the memory loss:
Note that if the destructor of the object whos delete needs to be called performs some non-trivial operation and your program depends on the side effects produced by it then your program falls prey to Undefined Behavior[Ref 1]. Once that happens all bets are off and your program may show any beahvior.
Also, An OS usually reclaims the allocated memory but not the other resources, So you might leak those resources indirectly. This may include operations dealing with file descriptors or state of the program itself etc.
Hence, it is a good practice to always deallocate all your allocations by calling delete or delete [] before exiting your program.
[Ref 1]C++03 Standard 3.8 Para 4:
"....if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior."
IMO it is best to always call delete properly:
to make it an automatic habit, making it less likely to forget it when it is really needed
to cover cases when non-memory resources (sockets, file handles, ...) need to be freed - these aren't automatically freed by the OS
to cater for future refactoring when the code in question might be moved out of main scope
Yes, you should call delete, at least because it's best practice. If you have important logic in your destructor, that's one extra reason that you should call delete.
Corrected: If the program depends on logic in the destructor, not calling delete explicitly results in undefined behavior.
The reason why this seems a bit redudant to me is that when main ends,
the program also ends, so there is no need to worry about memory
leaks.
You're right, but consider this: you create a class object which opens a connection to remote DB. After your program will complete, you should tell the DB "I'm done, i'm going to disconnect", but it won't happen in the case you won't call delete properly.
Its the best practice to de-allocate memory that's been allocated. You should keep in mind that Heap memory is limited and just allocating with out de-allocating while your program is running might run the heap space out for some other/or the same program(if its some kind of a daemon that is meant to run for a very long time) that needs heap.
Of course memory will be reclaimed by the operating system at the end of the program's execution.
I see you are using ROOT (CMS guy?). I think ROOT takes care of this and cleans up, doesn't it?
Best practices:
Do not use new, use automatic allocation
When dynamic allocation is necessary, use RAII to ensure automatic cleanup
You should never have to write delete in applicative code.
Here, why are you calling new for TGraph ?
TGraph A(...);
works better: less worries!
I understand that this may be construed as one of those "what's your preference" questions, but I really want to know why you would choose one of the following methods over the other.
Suppose you had a super complex class, such as:
class CDoSomthing {
public:
CDoSomthing::CDoSomthing(char *sUserName, char *sPassword)
{
//Do somthing...
}
CDoSomthing::~CDoSomthing()
{
//Do somthing...
}
};
How should I declare a local instance within a global function?
int main(void)
{
CDoSomthing *pDoSomthing = new CDoSomthing("UserName", "Password");
//Do somthing...
delete pDoSomthing;
}
-- or --
int main(void)
{
CDoSomthing DoSomthing("UserName", "Password");
//Do somthing...
return 0;
}
Prefer local variables, unless you need the object's lifetime to extend beyond the current block. (Local variables are the second option). It's just easier than worrying about memory management.
P.S. If you need a pointer, because you need it to pass to another function, just use the address-of operator:
SomeFunction(&DoSomthing);
There are two main considerations when you declare a variable on the stack vs. in the heap - lifetime control and resource management.
Allocating on the stack works really well when you have tight control over the lifetime of the object. That means you are not going to pass a pointer or a reference of that object to code outside of the scope of the local function. This means, no out parameters, no COM calls, no new threads. Quite a lot of limitations, but you get the object cleaned up properly for you on normal or exceptional exit from the current scope (Though, you might want to read up on stack unwinding rules with virtual destructors). The biggest drawback of the stack allocation - the stack is usually limited to 4K or 8K, so you might want to be careful what you put on it.
Allocating on the heap on the other hand would require you to cleanup the instance manually. That also means that you have a lot of freedom how to control the lifetime of the instance. You need to do this in two scenarios: a) you are going to pass that object out of scope; or b) the object is too big and allocating it on the stack could cause stack overflow.
BTW, a nice compromise between these two is allocating the object on the heap and allocating a smart pointer to it on the stack. This ensures that you are not wasting precious stack memory, while still getting the automatic cleanup on scope exit.
The second form is the so called RAII (Resource Acquisition Is Initialization) pattern. It has many advantages over the first.
When use new, you have to use delete yourself, and guarantee it will always be deleted, even if an exception is thrown. You must guarantee all that yourself.
If you use the second form, when the variable goes out of scope, it is always cleaned up automatically. And if an exception is thrown, the stack unwinds and it is also cleaned up.
So, you should prefer RAII (the second option).
In addition to what has been said so far, but there are additional performance considerations to be taken into account, particularly in memory-allocation-intensive applications:
Using new will allocate memory from the heap. In the case of intense (extremely frequent) allocation and deallocation, you will be paying a high price in:
locking: the heap is a resource shared by all threads in your process. Operations on the heap may require locking in the heap manager (done for you in the runtime library), which may slow things down significantly.
fragmentation: heap fragments. You may see the time it takes malloc/new and free/delete to return increase 10-fold. This compounds with the locking problem above, as it takes more time to manage a fragmented heap and more threads queue up waiting for the heal lock. (On Windows there is a special flag you can set for the heap manager so it heuristically attempts to reduce fragmentation.)
Using the RAII pattern, memory is simply taken off the stack. Stack is a per-thread resource, it does not fragment, there is no locking involved, and may turn out to play in your advantage in terms of memory locality (i.e. memory caching at the CPU level.)
So, when you need objects for a brief (or scoped) period of time, definitely use the second approach (local variable, on the stack.) If you need to share data between threads, use new/malloc (on one hand you have to, on the second hand these objects are typically long-lived enough so you pay essentially 0-cost vis-a-vis the heap manager.)
The second version will unwind the stack if an exception is thrown. The first will not. I don't see much difference otherwise.
The biggest difference between the two is that the new initiates a pointer to the object.
By creating the object without new, the object initiated is stored on the stack. If it is initiated with new, it returns a pointer to the new object that has been created on the heap. It actually returns a memory address that points to the new object. When this happens, you need to memory manage the variable. When you are done using the variable, you would need to call delete on it to avoid a memory leak. Without the new operator, when the variable goes out of scope the memory will be freed automatically.
So if you need to pass the variable outside of the current scope, using new is more efficient. However, if you need to make a temporary variable, or something that will only be used temporarily, having the object on the stack is going to be better, since you don't have to worry about memory management.
Mark Ransom is right, also you'll need to instantiate with new if you are going to pass the variable as a parameter to the CreateThread-esque function.