You are addicted to a garbage collector and your compiler maintaining the lifetime of your variables.
C++ Variable Lifetime 101:
There are at least four kinds of variable lifetimes in C++.
Stack
Heap
Global
Static Local
Variables of each type have a different lifetime. The lifetime of a variable is the time during which you can legally access the variable -- reading it afterwards or before that lifetime is illegal and results in undefined behaviour.
(In theory, a compiler could notice undefined behaviour, then read your web browser cache, extract your credit card numbers, and buy 1000 benie babies to be shipped to Egypt, and still follow the standard. However, it usually means that you will get random behaviour, sometimes it might work, other times it might crash your program.)
Stack: Items of stack, or automatic, lifetime exist
only during the scope in which they have been created. An example of a stack lifetime is:
- Code: Select all
int* foo() {
int bar = 7;
return 0;
}
The variable "bar" only exists during the squigly braces {} -- after that, it no longer exists. If your function foo() returned a pointer to bar, using that pointer would result in undefined behaviour.
You are actually doing that in the last bit of code you posted.
The Stack is a stack. When you call a function, the variables are pushed onto the stack, and then the function reads the variables off the stack. The local variables in the function are also placed on the stack. Stack variables are nice because of how simple they are to determine lifetime -- they allocate faster than the alternatives, and go away after a bounded period of time.
Heap:
The Heap is what you get when you call new. Heap objects have a dynamic lifetime -- their lifetime is determined by your code logic. You get rid of a Heap variable by calling delete.
There is a parallel C heap system using malloc/free/calloc. You should avoid using both in the same program.
The heap is a pool of memory blocks that is searched whenever you call new. Each new takes a non-zero time to run. You want to minimize the calls to new when running kernel-level code and when running "per pixel" code (ie, code that must run millions of times per second) at the current level of computer power, but outside of such situations new is pretty cheap.
Keeping track of the lifetime of heap variables is a hard problem. You must figure out when the last pointer to a heap variable goes away, and call delete on it. You must never reference heap data after it has been deleted.
Global:
This data is brought into being at the start of program execution, before main() runs, and is cleaned up after main() ends. The order it is brought into being and goes away is a bit unpredictable, so it sucks in that way. Plus it never goes away, even if you are finished using it. Global variables are an example of global program state. Ideally, you want the state of each function in your application to be describable and understandable by a human -- and every bit of global state makes this harder and harder and less likely to happen.
Static Local:
This is very much like global state, but the variable is first brought into being when the function is first called. This can cause all sorts of race condition and initialization order problems, and solve all sorts of race condition and initialization problems.
In general, both Global and Static Local data causes problems when your program becomes threaded, or is extended in ways you didn't predict.
...
That help?