  | 
   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.
 
 
 |