class A ;A a ;
A* b = new A() ;变量a为栈变量,b为堆变量。a不能跨线程传递,因为不能确保传递a的线程
在传递结束后是否退出(a的生存期不确定);但b可以。问题:
如何确定一个变量是堆类型还是栈类型,因为如果需要传递一个实例到另外
一个线程,在无法确定其是否为堆变量的情况下,如:
void MyThreadProc()
{
   A a ;
   A* b = new A() ;   CallOtherThread(&a) ;
   CallOtherThread(b) ;
}
对CallOtherThread来说如何区别这个对像是堆变量还是栈变量就很重要,否
则只能所有的都进行克隆,而如果这个对像是一个相当复杂的复合对像,其
开销也将相当大。提问:是否有API或其它手段来(如通过内存地址的值)来判断一个实例是堆
实例还是栈实例???验证可行立即给分!!!!

解决方案 »

  1.   

    为什么需要通过API来确定呢?代码是你写的,你还不知道它是什么变量?就算不是你写的,你也可以通过搜索代码来确定它到底是什么啊。
      

  2.   

    CallOtherThread写成两个函数。
    void CallOtherThread(A obj);
    void CallOtherThread(A *obj);然后调用的时候总是直接写CallOtherThread(a),千万不要写&a *a之类的就行了。
      

  3.   

    判断在不在栈上很容易(I386上系列上都没问题)
    void onstack(void *o)
    {
            if (&o < o)
                    printf ("on stack\n");
            else
                    printf ("not on stack\n");
    }不过静态数据和堆数据不好区分。
      

  4.   

    回zengpan_panpan int main()
    {
    int i = 0 ;
    onstack(&i) ;
    int* j = new int ;
    onstack(j) ;
    getchar() ;
    return 0;
    }很遗憾,验证未通过,两个都打印出"on stack"
      

  5.   

    一般在线程函数里面要处理的数据不是全局可访问的数据就是通过线程函数参数解析出来的Buffer指针,一般都不会去访问一个随时可能析构的局部对象。
      

  6.   

    不行只是说上名的方法不行。不要误会了,一定需要的话还是有方法的。上面的代码其实已经提示方法了,不过vc环境不同而已,但是可以改造一下。提示一下:关键就在于栈的生长方向和堆的生长方向相反。程序入口记录当前esp,如果比esp小的就在栈上,否则不是。void onstack(void *o)
    {
    static void *p;
    if (!p) p = o;
            if (o <= p)
                    printf ("on stack\n");
            else
                    printf ("not on stack\n");
    }void test2()
    {
    int i = 0 ;
    onstack(&i) ;
    int* j = new int ;
    onstack(j);
    }int main()
    {
    int i = 0 ;
    onstack(&i);
    int* j = new int ;
    onstack(j);
    test2();
    int k = 0;
    onstack(&k);
    getchar() ;
    return 0;
    }
    当然,这里需要在主函数内用第一个栈变量初始化onstack里面的p;