Beispiel #1
0
/*
 * set both the signatures for a chunk to a particular value
 * 'chunk' must be the index of the bottom signature for a chunk
 * NOTE: if you change the size of this chunk with this function
 * then we'll set the end signature for the NEW SIZE!
 */
void setBothSignatures(unsigned chunk, int value) {
    unsigned top;

    memory_pool[chunk] = value;
    top = topSignature(chunk);
    memory_pool[top] = value;
}
Beispiel #2
0
void displayChunks(void) {
    int size;
    int num_chunks = 0;
    unsigned chunk = 0;
    int top_signature;

    while (chunk < pool_size) {
        num_chunks += 1;
        size = memory_pool[chunk];
        printf("chunk %d ", num_chunks);
        top_signature = memory_pool[topSignature(chunk)];
        if (size != top_signature) {
            printf(" has a signature mismatch problem! oh fudge\n");
            exit(-1);
        }
        if (size > 0) {
            printf(" is available");
        }
        else {
            printf(" is in use");
        }
        if (size < 0) { size = -size; }
        printf(" and has %d words of available storage\n", size);


        chunk = successorChunk(chunk);
    }
}
Beispiel #3
0
void deallocateMemory(void *p)
{
    /* since the available memory is one position above the signature
     * the signature can be found at one position below the first
     * byte of available memory
     */
    int *chunk_address = ((int *)p) - 1;
    unsigned chunk;
    int top_signature;
    int bottom_signature;
    int size;

    if ((chunk_address < memory_pool)
        || (chunk_address >= &memory_pool[pool_size]))
    {
        /* due to silliness in the MetroWerks compiler, it is possible
         * for new to be called before the memory heap is on-line.  In that
         * case the system default heap is used, and not this one.
         * this generally only happens for global constructors, such as
         * the stuff associated with cout and cin.
         * When these objects are destroyed (after main ends) the
         * runtime system calls delete on all these things but
         * since our heap is now online, we get all the other heap's memory
         * back.  We're just going to ignore it.  The OS will clean up
         * that memory anyway when the application quits, so its
         * no big deal.
         */

        /* if you want to see this in action, de-comment the following line */
        // cout << "hey! that ain't mine, don't throw that junk at me\n";
        return;
    }
    chunk = chunk_address - memory_pool;

    bottom_signature = memory_pool[chunk];
    top_signature = memory_pool[topSignature(chunk)];

    /* another sanity check, not really insane at all. */
    assert(bottom_signature == top_signature
           && bottom_signature < 0);

    size = -bottom_signature;
    setBothSignatures(chunk, size);

    mergeChunkIfOK(chunk);

    if (chunk > 0)
    { // this is not quite silly, chunk could be equal to zero
        unsigned previous_chunk = predecessorChunk(chunk);
        mergeChunkIfOK(previous_chunk);
    }

    if (mem_leak_check && isEmptyHeap())
    {
        std::cout << "Yay, you do not have a memory leak!" << std::endl;
    }
}
Beispiel #4
0
/*
 * sanity check the heap and return true if it looks OK,
 * return false if something is messed up
 */
bool isSaneHeap(void) {
    unsigned chunk = 0;

    /* check each chunk to see if top and bottom sigs match */
    while (chunk < pool_size) {
        if (memory_pool[chunk] != memory_pool[topSignature(chunk)]) {
            return false;
        }
        chunk = successorChunk(chunk);
    }
    return true;
}