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