Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++ For Dummies (2004) [eng].pdf
Скачиваний:
84
Добавлен:
16.08.2013
Размер:
8.09 Mб
Скачать

Chapter 8: Taking a First Look at C++ Pointers 121

Execution begins with main(). The function main() immediately invokes parent(). The first thing that the processor sees in parent() is the declara­ tion of intParent. At that point, intParent goes into scope — that is, intParent is defined and available for the remainder of the function parent().

The second statement in parent() is the call to child(). Once again, the function child() declares a local variable, this time intChild. The variable intChild is within the scope of child(). Technically, intParent is not within the scope of child() because child() doesn’t have access to intParent; however, the variable intParent continues to exist.

When child() exits, the variable intChild goes out of scope. Not only is intChild no longer accessible, but it no longer even exists. (The memory occupied by intChild is returned to the general pool to be used for other things.)

As parent() continues executing, the variable intLater goes into scope at the declaration. At the point that parent() returns to main(), both intParent and intLater go out of scope. The programmer may declare a variable outside of any function. This type of variable, known as a global variable, remains in scope for the duration of the program.

Because intGlobal is declared globally in this example, it is available to all three functions and remains available for the life of the program.

Examining the scope problem

The following code segment compiles without error but doesn’t work (don’t you just hate that):

double* child(void)

{

double dLocalVariable; return &dLocalVariable;

}

void parent(void)

{

double* pdLocal; pdLocal = child(); *pdLocal = 1.0;

}

The problem with this function is that dLocalVariable is defined only within the scope of the function child(). Thus, by the time the memory address

122 Part II: Becoming a Functional C++ Programmer

of dLocalVariable is returned from child(), it refers to a variable that no longer exists. The memory that dLocalVariable formerly occupied is proba­ bly being used for something else.

This error is very common because it can creep up in a number of different ways. Unfortunately, this error does not cause the program to instantly stop. In fact, the program may work fine most of the time — that is, the program continues to work as long as the memory formerly occupied by dLocalVariable is not reused immediately. Such intermittent problems are the most difficult ones to solve.

Providing a solution using the heap

The scope problem originated because C++ took back the locally defined memory before the programmer was ready. What is needed is a block of memory controlled by the programmer. She can allocate the memory and put it back when she wants to — not because C++ thinks it’s a good idea. Such a block of memory is called the heap.

Heap memory is allocated using the new command followed by the type of object to allocate. For example, the following allocates a double variable off the heap.

double* child(void)

{

double* pdLocalVariable = new double; return pdLocalVariable;

}

Although the variable pdLocalVariable goes out of scope when the func­ tion child() returns, the memory to which pdLocalVariable refers does not. A memory location returned by new does not go out of scope until it is explicitly returned to the heap using a delete command:

void parent(void)

{

//child() returns the address of a block

//of heap memory

double* pdMyDouble = child();

//store a value there *pdMyDouble = 1.1;

//...

Chapter 8: Taking a First Look at C++ Pointers 123

//now return the memory to the heap delete pdMyDouble;

pdMyDouble = 0;

//...

}

Here the pointer returned by child() is used to store a double value. After the function is finished with the memory location, it is returned to the heap. The function parent() sets the pointer to zero after the heap memory has been returned — this is not a requirement, but a very good idea. If the pro­ grammer mistakenly attempts to store something in * pdMyDouble after the delete, the program will crash immediately.

A program that crashes immediately upon encountering an error is much easier to fix than one that is intermittent in its behavior.

The whole problem of allocating and returning heap memory goes away in Visual C++.NET–managed mode. Managed refers to the fact that C++ handles the allocation and deallocation of memory references. This book deals only with unmanaged mode Visual C++.NET programs.

124 Part II: Becoming a Functional C++ Programmer