Whoa, whoa! ...Whoa...
First of all, the keyword
new
is used to allocate memory on the
heap, not the stack. If you want to declare a large amount of memory on the
stack and control when it is "deleted", use a "naked block." E.g.
1 2 3 4 5 6 7 8 9 10
|
Type x;
{ //this is a naked block
BigType y;
y.foo();
y.bar(x);
}
//y is no longer in scope, therefor its destructor was called and the stack pointer was reset
// also, there is no "bad" pointer floating around, and the identifier "y" can be reused
|
Second (and arguably less important), a pointer is only 4 bytes in a
32 bit program. (Get it? 4
bytes == 32
bits.)
Third. You do not need to use pointers to pointers to make a 2D array. Programmers only do that when they want their 2D array syntax to look like they are used to. E.g.
1 2 3 4 5 6 7 8 9 10 11 12
|
//these are not const, and can not be used to declare an array on the stack
int width = ...;
int height = ...;
T *array = new T[width * height];
//iterate through the "2D" array
for( int row = 0; row < height; row++ )
for( int col = 0; col < width; col++ )
do_something_with( array[row * height + col] ); //~ array[row][col]
delete[] array;
|
Note however that a dynamic array of arrays should (or could) be a pointer to a pointer if both the outer array's size and each inner array's size was determined at run time;
and the inner arrays might not all be the same size. E.g. outer array of classes, inner sub-arrays are the rosters of those classes. Each class might have a different number of students, and the number of classes may be dynamic (or at least unknown at compile-time.)
----------------------------------------------------------------------------------------------------------------------------------
To answer the OP:
A pointer is an address. Just like everything else in a computer, these addresses are numbers (usually represented in hex, and whose size is dependent on your CPU and compiler. Yes a 64 bit program has larger pointers then a 32 bit one. This gives them more addresses to work with though. Think about this: if every house could only have a 4 digit address, you could only have 10000 houses. So although these 4 digit address would be easier/quicker to write then our current -- number street, city state, blah blah -- they would be impractical.) So why do we, as programers, care about these internal numbers. Let's say I need to hire a designer for my house (they would be represented as a function in our program, and our house would be a variable... a big variable.) Would it (a) be easier to tell him my address, or (b) build a copy of my house and send that to him?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
//pass a copy (copied implicitly)
Design designer(House project) {
do_stuff_with( project );
...
}
//pass only the address (no copying)
Design designer(House *project) {
do_stuff_with( *project ); //need to dereference the pointer
...
}
int main() {
House myHouse;
desinger( myHouse ); //for (a) pass-by-copy
designer( &myHouse ); //need to get address for (b) pass-by-pointer
...
return 0;
}
|
(b) is clearly a faster and more efficient alternative to (a), if we trust the designer to not steel stuff from our house. Of course I'm joking, but not entirely. This is a real concern for the programmer. If we don't know who wrote the code for the
designer function, and we don't/can't actually read through it, we might not want to pass our house to it, or our house might not come back the same as when it went in.
However, it's worth pointing out (bad pun intended) that C++ (not C) provides an alternative.
1 2 3 4 5 6 7 8 9 10 11 12
|
//pass a reference to the house (no copying)
Design designer(House &project) {
do_stuff_with( project ); //no need to dereference any pointers
...
}
int main() {
House myHouse;
designer( myHouse ); //no need to get address
...
return 0;
}
|
Here we get all the "benefits" of copying only the address and not copying the house, but we never need to explicitly get the address or dereference it. The only caveat is that a reference can not be
NULL, i.e. it must actual point to something.
Another thing to note (in C++ only) is that in my above code, dealing with 2D arrays, I could have avoided the explicit
new and
delete operations by using a standard library like
<vector>. These objects will allocate the memory need, and deallocate it when done, automatically. (This idea of hiding specific details of an algorithm is known as "encapsulation", and the C++ standard libraries make excellent use of it.)
----------------------------------------------------------------------------------------------------------------------------------
In short:
If you're using C++, you likely wont deal much with pointers. (Mainly only when you need
NULL, are utilizing a C library, or are asked to for some school assignment.)
If you're using C, get used to them! They allow for faster programs, and allocation of data on the heap.