call stack

When you make a function call, the computer saves on the stack (on the top, of course) four things, which are listed here. Note that this process is true for all function calls, not just those that are recursive: 1. (still in your function) The parameters you are passing to the function. 2. (as it travels to the other function) The code location to return to when the called function is completed. 3. (inside the called function) Your “base pointer” so that it will be able to restore it when it is done. It then sets the base pointer to the current stack location, for its own use. The base pointer is how it finds both the parameters you passed in and the local variables for which it is about to allocate space on the stack. 4. (inside the called function) Space for any local variables the function needs. Of course, your function went through these same steps when it was called. In your function, every time you access one of the parameters you passed in or one of the automatic variables you declared as local to your function, the function pulls these values out of memory at a location defined by the base pointer—plus or minus some known amount. When a function returns, it undoes all these steps, in reverse order: The function deallocates the space for local variables, restores the base pointer of the caller, and returns to the code address saved (popping that address off the stack at the same time). Finally, the function deallocates the space for the parameters that were passed in. When a function calls itself, this process doesn’t change. In fact, the compiler does not even know the difference. But we can see that this process supports the effect we want. Each time our recursive function calls itself, new copies of the parameters are saved on the stack, the return address is saved if we are in the middle of evaluating an expression (as in the Fibonacci function), and the new recursion allocates its own space for all the local variables. In the function Directory::Display(), for example, the variable newPrefix is allocated fresh each time the function is called. This arrangement does not interfere with other versions of that variable that are still alive inside earlier recursions of the function. Now we can consider the effects of infinite recursion—that is, recursion for which the author did not properly confirm the termination requirements. Every time you recurse, some amount of stack space is used. Even if you created a recursive function with no parameters and no local variables, you cannot get around the need to save the base pointer and the return address. If your function never stops recursing, it will grow the stack until the memory allocated for the stack is used up. Typically, the stack space is adjacent to the global memory that will be tromped on in the computer’s desperate attempt to save base pointers and return addresses. Eventually, your computer will write over something critical or it will have a memory fault. In either case, your program will halt (or maybe your whole computer will halt). Because this is rarely the desired result, you should check your termination requirements carefully.
發佈了7 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章