⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gcalloc.h

📁 国外经典教材《程序设计抽象思想—C语言描述》一书中的关键性库文件
💻 H
字号:
/* * File: gcalloc.h * Last modified on Sat Aug 28 10:17:26 1993 by eroberts * ----------------------------------------------------- * This file defines the interface for a garbage-collecting * allocator.  This interface defines only an initialization * function (InitGCAllocator) and facilities for protecting * global variables.  The actual allocation is handled by * the standard GetBlock and FreeBlock functions defined in * genlib.h.  These functions use the garbage-collecting * allocator if InitGCAllocator has been called. */#ifndef _gcalloc_h#define _gcalloc_h#include <stdlib.h>#include "genlib.h"/* * Background * ---------- * In a typical application program, memory is allocated in * three different regions.  Static data is stored in fixed * memory addresses and is declared in C using the storage * classes static or extern (extern is in fact omitted in * the defining instance).  Automatic data (the default * storage class for variables defined within a function) * is stored on the control stack, where it is allocated * when a function is called and deallocated on return * from that function.  In addition to these two classes, * however, many programs will need to allocated additional * memory from an expandable pool called the "heap."  All * memory in the heap is addressed via pointers, which are * generated as the program runs. * * Although heap allocation is extremely convenient, * particularly when used in library implementations, it * suffers from an important failing.  The problem is not * identifying what parts of the program have responsibility * for allocating memory.  That task is easy.  The thorny * issue is who has responsibility for freeing previously * allocated memory when it is no longer needed. * * The central problem is that the operations of allocating * and freeing memory are most naturally situated on opposite * sides of the interface boundary between an implementation * and its client.  The implementation knows when to allocate * memory and simply returns pointers to the client.  The * implementation, however, has no idea when the client is * finished with the allocated object, so that freeing the * storage has to remain the client's responsibility, even * though the client may not understand enough about the * object's structure to do so. * * To get around this problem, most libraries have been * designed in one of two ways.  One approach is to make * the client responsible for allocating storage and * passing a pointer to the implementation.  The alternative * is to provide procedures in each interface that free any * storage allocated by the abstraction.  Each of these * approaches is decidedly non-optimal. * * A completely different alternative is to use a strategy * called "garbage collection."  Under this strategy, * implementations are free to allocate memory and pass * their addresses back to the client.  As long as the * client holds that pointer, the memory is considered * to be in use.  When the pointer goes away (which occurs * when a different pointer is assigned to the variable or * when the variable holding the pointer is deallocated * by returning from the function declaring it), the * storage to which it referred is no longer accessible, * and can be reallocated to new purposes. * * Detecting what memory is garbage does not happen as the * memory becomes inaccessible.  Instead, the traditional * garbage-collection strategy is to wait until a memory * cannot be satisfied, and then to go through accessible * memory to see what previously allocated blocks are no * longer reachable, freeing these for reuse. *//* * Client responsibilities * ----------------------- * The garbage-collecting allocator imposes some important * responsibilities on the client who uses the package.  In * particular, the client must agree to obey the following * rules: * *   (1)  Whenever a heap object is allocated, the client *        must agree to keep at least one copy of the *        original pointer returned by GetBlock.  In C, *        it is common to use pointer arithmetic to adjust *        a pointer so that, for example, it points to the *        interior of an array.  The rule is that a block *        is protected from garbage collection only by *        a pointer to its beginning and not to its *        interior.  Note that this rule does not prohibit *        pointing to the interior of the block; the *        implication is simply that the client must *        also keep the original pointer around. * *   (2)  The garbage collector must be able to identify *        all places in which valid heap pointers might *        be maintained, so that it can ensure that *        valid data is not collected by accident.  This *        package (subject to the system assumptions *        below) is able to find pointers living in *        automatic variables on the stack, or in heap *        blocks allocated by GetBlock which themselves *        remain accessible (see condition 3 as well).  If *        static variables contain allocated data, however, *        the client must warn the allocator of this *        fact by calling * *                ProtectVariable(variable); * *        where variable is the name of the global *        variable. * *   (3)  It is the client's responsibility to free *        explicitly any storage allocated outside of the *        GetBlock/FreeBlock mechanism.  Moreover, it is *        also important to remember that the garbage *        collector is not able to find pointers which are *        stored in dynamically allocated blocks unless *        those blocks were allocated by GetBlock.  Thus, *        if an implementation makes direct calls to the *        system allocation functions in addition to *        GetBlock, that implementation may not store the *        GetBlock pointers in the system-allocated memory. *//* * Function: InitGCAllocator * Usage: InitGCAllocator(&argc); * ------------------------------ * This call enables the garbage-collecting allocator and * also establishes the base of the stack for tracing.  This * call should be made from main, and the address passed * should be the address of the argc parameter. */void InitGCAllocator(void *stackbase);/* * Macro: ProtectVariable * Usage: ProtectVariable(v); * -------------------------- * Registers a global variable with the allocation system, so * that the variable is traced when the garbage collector is * used.  This operation needs to be provided in "genlib.h" * so that code can be written to function correctly whether * or not the garbage-collecting allocator is loaded. */#define ProtectVariable(v) ProtectBlock(&v, sizeof v)/* * Function: ProtectBlock * Usage: ProtectBlock(ptr, nbytes); * --------------------------------- * This function is not usually called by clients (who will * ordinarily use ProtectVariable instead), but has the * effect of protecting the block of memory beginning at * ptr and extending for nbytes from the garbage collector. */void ProtectBlock(void *ptr, size_t nbytes);/* * Global linkage variable: _acb * ----------------------------- * This variable is used to hold the allocation control block * that provides the linkage between this package and the * dynamic allocator.  The reason for using the structure * as a linkage is so that the garbage-collecting allocator * need not even be loaded if it is not explicitly called. */typedef struct {    void *(*allocMethod)(size_t nbytes);    void (*freeMethod)(void *ptr);    void (*protectMethod)(void *ptr, size_t nbytes);} *_GCControlBlock;extern _GCControlBlock _acb;#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -