This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Object On The Stack Submitted by

isInStack(ptr) tests if an object pointed by ptr has been created to the stack or not. Motivation: When doing reference counting you want to assert you're not about to delete an object which has been allocated to the stack. Tested in following platforms:

> - MSVC6, Win2k
> - gcc 2.95.2, Win2k
> - gcc 2.95.2, Linux (RedHat)
> - gcc 2.8.1, Digital UNIX V4.0F

Makefile and MSVC6 project files are included.
Known issues:

> - I haven't given any thought how this works in a shared library (dll/so)
> - Multithreading is supported only in Win32/MSVC

Jani Kajala PS. Why I didn't use !_CrtIsValidHeapPointer(p) of MSVCRT? 1) portability 2) coolness factor ;)

Currently browsing [isInStack.zip] (3,545 bytes) - [isInStack.h] - (2,084 bytes)

    /*
     * isInStack 1.0
     *
     * isInStack(ptr) tests if an object pointed by ptr
     * has been created to the stack or not.
     *
     * Motivation: When doing reference counting you
     * want to assert you're not about to delete an object
     * which has been allocated to the stack.
     *
     * Tested in following platforms:
     * - MSVC6, Win2k
     * - gcc 2.95.2, Win2k
     * - gcc 2.95.2, Linux (RedHat)
     * - gcc 2.8.1, Digital UNIX V4.0F
     *
     * Makefile and MSVC6 project files are provided.
     *
     * Known issues:
     * - I haven't given any thought how this works in a shared library (dll/so)
     * - Multithreading is supported only in Win32/MSVC
     *
     * Feb 7, 2002,
     * Jani Kajala (jani.kajala@helsinki.fi)
     *
     * PS.  Why I didn't use !_CrtIsValidHeapPointer(p) of MSVCRT?
     *      1) portability 2) coolness factor ;)
     */
    #ifndef _ISINSTACK_H
    #define _ISINSTACK_H

    /**
     * Initializes isInStack.
     * The init must be called in a higher level function than
     * where the isInitStack() is actually used.
     *
     * If multiple threads are used then the init needs to be called
     * at the beginning of each thread. Note that the thread function
     * calling isInStackInit must again be higher level than functions where
     * isInThread is actually used.
     */
    void    isInStackInit();

    /**
     * Returns true if the pointed object has been created in the stack
     * of the calling thread.
     */
    bool    isInStack( const void* p );

    /** Returns number of bytes of stack used by the calling thread. */
    int     usedStackSize();

    #endif // _ISINSTACK_H
    /*
     * Copyright (c) 2002 Jani Kajala
     *
     * Permission to use, copy, modify, distribute and sell this
     * software and its documentation for any purpose is hereby
     * granted without fee, provided that the above copyright notice
     * appear in all copies and that both that copyright notice and
     * this permission notice appear in supporting documentation.
     * Jani Kajala makes no representations about the suitability
     * of this software for any purpose. It is provided "as is"
     * without express or implied warranty.
     */

Currently browsing [isInStack.zip] (3,545 bytes) - [isInStack.cpp] - (1,272 bytes)

    #include "isInStack.h"

    //------------------------------------------------------------------------

    // thread local storage
    #ifdef _MSC_VER
    #define THREADLOCAL __declspec(thread)
    #else
    #define THREADLOCAL
    #endif

    //------------------------------------------------------------------------

    /** Thread-specific stack bottom pointer. */
    THREADLOCAL static const char* s_stackBottom = 0;

    //------------------------------------------------------------------------

    static int getFrameSize( char* x )
    {
        char y = 0;
        return x - &y;
    }

    void isInStackInit()
    {
        char x = 0;
        s_stackBottom = &x + getFrameSize(&x) * 2;
    }

    bool isInStack( const void* ptr )
    {
        const char* p           = (const char*)ptr;
        char        x           = 0;
        const char* stackTop    = &x;

        if ( stackTop > s_stackBottom )
            return p > s_stackBottom && p < stackTop; // stack grows up
        else
            return p > stackTop && p < s_stackBottom; // stack grows down
    }

    int usedStackSize()
    {
        char        x           = 0;
        const char* stackTop    = &x;

        if ( stackTop > s_stackBottom )
            return stackTop - s_stackBottom; // stack grows up
        else
            return s_stackBottom - stackTop; // stack grows down
    }

Currently browsing [isInStack.zip] (3,545 bytes) - [test.cpp] - (1,042 bytes)

    #include "isInStack.h"
    #include <stdio.h>

    //------------------------------------------------------------------------

    #define REQUIRE( A )    {if (!(A)) printf( "Assertion failed at %s(%i)\n", __FILE__, __LINE__ );}

    //------------------------------------------------------------------------

    class MyClass
    {
    };

    //------------------------------------------------------------------------

    static void func()
    {
        char testArray[123] = {0};
        int size = usedStackSize();
        printf( "usedStackSize in %s(%i) is %i\n", __FILE__, __LINE__, size );

        REQUIRE( isInStack(&size) );
        REQUIRE( isInStack(testArray) );
    }

    static void test()
    {
        char testArray[20] = {0};
        MyClass a;
        MyClass* b = new MyClass;
        MyClass* c = new MyClass;
        MyClass d;

        func();

        REQUIRE( isInStack(&a) );
        REQUIRE( !isInStack(b) );
        REQUIRE( !isInStack(c) );
        REQUIRE( isInStack(&d) );

        delete b;
        delete c;
    }

    int main()
    {
        isInStackInit();
        test();
        return 0;
    }

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.