The Path to Swap, Part I: Automatic and Dynamic Variables
Dynamic memory has turned out to be both a blessing and a curse. I mean, unless you are doing something truly trivial, such as, say, a beginner C++ homework assignment, you are using it in one form or another. It seems that any language that has come out since Java has settled on using references and garbage collection. The question is, was this the right choice?
To see why references and garbage collection are so popular, it helps to see what the standard alternative is. By that, I mean the model employed by C and C++.
Note to people who care: I am aware of doing things like overriding new or using a different memory allocator to get garbage collection, or the use of autoptr and smartptr and all of those things. When I say the model used by C and C++, I mean the default one.In C++, there are two main types of variables, automatic and dynamic. An automatic variable is one that is created for you, and destroyed for you. You don't have to worry about it. Consider when you want to do some integer math. In C++, you might do the following.
#include <iostream>
using namespace std;
int main()
{
int a, b, c;
a = 2;
b = 3;
c = a + b;
cout << "a = " << a << ", b = " << b << " c = " << c << endl;
}
This should output “a = 2, b = 3, c = 5”. The specific details are left unspecificied when it comes to C and C++ (although almost all of them tend to do it the same way), but the basics usually amount to: - Memory is allocated to a, b, and c. They will even be allocated next to each other.
a
is set to 2b
is set to 3c
is set to the result of adding 2 and 3- The result is outputted
- The memory for
a
,b
, andc
is deallocated
a
, b
, and c
are taken care of you. You simply declare them.
And if there were constructors and destructors, those would have been called when the memory was allocated and deallocated, respectively.Dynamic variables, and subsequently dynamic memory, are different. We handle the memory allocation, and its subsequent destruction. Here’s how you might do the same thing using dynamic memory in C++.
#include <iostream>
using namespace std;
int main()
{
int *a, *b, *c;
a = new int;
b = new int;
c = new int;
*a = 2;
*b = 3;
*c = (*a) + (*b);
cout << "a = " << *a << ", b = " << *b << ", c = " << *c << endl;
delete a;
delete b;
delete c;
}
The description of what happens is relatively similar, and anyone who has ever done anything in C++ would know that this was very silly to do. For those that have never done any such thing, you’ll mainly feel like there are a lot of extra asterisks around. Also, we used the words new and delete are strewn all about. Sufficed to say, new allocates memory, while delete deallocates it for us. And again, constructors and destructors would be called.Hopefully, it’s easy to see that this is fraught with potentials for making errors. What if we forgot to do a
new
, say on the a
? We said that a
pointed to a location in memory, but we have no idea where that is. So at best, bad things will happen. What about the delete
on a
? It doesn’t matter much here since the program quits immediately afterward, but the memory will be held on to until the program quits.
There must be some reason why we did this, right? So far, all we’ve done is make our life harder. Well, there is indeed. But that’ll have to wait for the next part of&dots;The Path to Swap.
Comments