这是一道中级题. 高级题其实还不如这道题                                                                                                              1) 指出以下示意代码的错误之处                                                        
                                                       
CRITICAL_SECTION g_CriticalSection=NULL;
char *g_string=NULL;
                                                                                                               
class MyClass
{
public:
        int InitInstance();
        int threadA();
};
                                                                                                               
int MyClass::Init()
{
        InitCriticalSection(&g_CriticalSection);
        CreateThread(threadA,...);
}
                                                                                                               
int MyClass::threadA()
{
        EnterCriticalSection(g_CriticalSection)
        if(g_string!=NULL)
        {
                delete g_string;
        }
        g_string = new char[1024];
        ...
        delete g_string;
        g_string = NULL;
        ExitCriticalSection(g_CriticalSection)
        return 0;
}2) 如果MyClass改成如下定义,请写出实现上面功能的代码
                                                                                                               
class MyClass
{
        static const CRITICAL_SECTION m_CriticalSection;
public:
        MyClass() { EnterCriticalSection(m_CriticalSection); }
        ~MyClass(){ ExitCriticalSection(m_CriticalSection); }
};

解决方案 »

  1.   

    int MyClass::Init()无此成员函数
    static int threadA();
    delete[] g_string;
    晕。
      

  2.   


    int MyClass::InitInstance();
      

  3.   

    delete g_string 没有错,这是因为char是基本类型,不用调用析构函数,当然提倡用delete[] g_string 
      

  4.   

    第一题
      1. 什么时候调用DeleteCriticalSection()???????
      2. delete[] g_string;
    第二题
      去掉中的static const CRITICAL_SECTION m_CriticalSection;的static??  只是猜测..
      

  5.   

    to:solar 为什么在:int MyClass::Init()
    {
            InitCriticalSection(&g_CriticalSection);
            ...
    }
    而在:int MyClass::threadA()
    {
            EnterCriticalSection(g_CriticalSection)
             ...
            ExitCriticalSection(g_CriticalSection)
            return 0;
    }
    (&g_CriticalSection)?
    (g_CriticalSection)?
    请解释一下
      

  6.   

    Free_Man(浪迹天涯),我觉得真正的错误还是没人指出啊
      

  7.   

    请那位大虾解释一下 为什么这样?
    为什么在:int MyClass::Init()
    {
            InitCriticalSection(&g_CriticalSection);
            ...
    }
    而在:int MyClass::threadA()
    {
            EnterCriticalSection(g_CriticalSection)
             ...
            ExitCriticalSection(g_CriticalSection)
            return 0;
    }
    (&g_CriticalSection)?
    (g_CriticalSection)?
    请解释一下
      

  8.   

    lbywyj(沙漠上建筑): 
    >>(&g_CriticalSection)?
    >>(g_CriticalSection)?题目中的代码基本是伪代码,仅示意作用,我想不应该细究具体的参数形式
      

  9.   

    小问题:
    CRITICAL_SECTION看样子不是一个宏就是一个结构,那么g_CriticalSection=NULL;
    就不好解释:如果是一个指针宏,那么宏的命名风格不好:完全看不出是个指针;如果是一个结构,那么这个初始化就是错误的。
    另一个问题:线程体设成public有问题,这样没有办法避免外部对这个线程函数的直接调用。所以似乎应该把threadA()声明成private;如果这个类是一个线程类的框架,需要根据需要改写线程体,那么应该把threadA声明成virtual protected。
      

  10.   

    solar,那真正的错误到底在那里呢?
      

  11.   

    LeaveCriticalSection(g_CriticalSection)
      

  12.   

    还有重要的一点:类内的线程函数必须声明为staticclass MyClass
    {
    public:
            int InitInstance();
            static       int threadA();
    };
      

  13.   

    同意seehigh(眼高手低)的意见.加static
      

  14.   

    这是windows编程中关于线程临界区的问题
    VOID EnterCriticalSection(
      LPCRITICAL_SECTION lpCriticalSection   // critical section
    );
    VOID InitializeCriticalSection(
      LPCRITICAL_SECTION lpCriticalSection  // critical section
    );
    都是windows API
    ExitCriticalSection 我没找到,我想应该是下面这个吧
    VOID LeaveCriticalSection(
      LPCRITICAL_SECTION lpCriticalSection   // critical section
    );
      

  15.   

    CRITICAL_SECTION g_CriticalSection=NULL   null去掉
      

  16.   

    题目记错了,我也去面试过
    线程中间有一个return -1;没有LeaveCriticalSection():(考点一 )
    线程应该为static(考点二)
    利用class的构造和析构调用Enter...和Leave...(临界区)(考点三)
      

  17.   

    static const CRITICAL_SECTION m_CriticalSection;
    在c++的类定义中不应该出现这样的定义吧!
      

  18.   

    我觉得问题出在开始的两个全局变量上!
        加入myclass有两个继承类,大家想想看,会出现什么问题!
      
        设为static我想就是为了解决这个问题!
        请多指教!
      

  19.   

    眼高手低是对的, 在线程中用到类里的函数必须是STATIC的, 还用就是delete [] g_string;
      

  20.   

    如果threadA抛出异常,可能死锁。
      

  21.   

    加try __finally 可以消除死锁
    EnterCriticalSection(g_CriticalSection)
      try{
            if(g_string!=NULL)
            {
                    delete g_string;
            }
            g_string = new char[1024];
            ...
            delete g_string;
            g_string = NULL;
      }
    __finally{
            ExitCriticalSection(g_CriticalSection);
            }
            return 0;
      

  22.   

    to wjsoft1(踏雪) 
    用SingLock类什么的
      

  23.   

    to  wjsoft1(踏雪)
    你在说什么啊,在C++程序中使用windows的结构化异常处理?
    这样做不好的,要用只能用C++异常处理
      

  24.   

    其实,这道题实质上是考临界区的问题。
    如果下列情况出现:
    MyClass m1;
    m1.InitInstance();
    m1.threadA();
    //m1的线程一直在执行,有实列m2也要执行threadA;
    MyClass m2;
    m2.InitInstance();
    m2.threadA();
    //m2照样可以执行,因为它也做了InitInstance动作。
    //所以会出现问题。应该使用构造函数来实现。
      

  25.   

    g_string 被delete 后还能赋值吗?那个ThreadA不是什么线程函数!
      

  26.   

    CRITICAL_SECTION g_CriticalSection=NULL;
    char *g_string=NULL;
                                                                                                                   
    class MyClass
    {
    public:
            int InitInstance();
            int threadA();
    };
                                                                                                                   
    int MyClass::Init()
    {
            InitCriticalSection(&g_CriticalSection);
            CreateThread(threadA,...);
    }
                                                                                                                   
    int MyClass::threadA()
    {
            EnterCriticalSection(g_CriticalSection)
            if(g_string!=NULL)
            {
                    delete g_string;
            }
            g_string = new char[1024];
            ...
            delete g_string;
            g_string = NULL;
            ExitCriticalSection(g_CriticalSection)
            return 0;
    }
      

  27.   

    改为:
    CRITICAL_SECTION g_CriticalSection;
    char *g_string=NULL;
                                                                                                                   
    class MyClass
    {
    public:
            int InitInstance();
            int threadA();
    };
                                                                                                                   
    int MyClass::Init()
    {
            InitCriticalSection(&g_CriticalSection);
            CreateThread(threadA,...);
    }
                                                                                                                   
    int MyClass::threadA()
    {
            EnterCriticalSection(&g_CriticalSection)
            if(g_string!=NULL)
            {
                    delete [] g_string;
            }
            g_string = new char[1024];
            ...
            delete [] g_string;
            g_string = NULL;
            ExitCriticalSection(&g_CriticalSection)
            return 0;
    }
      

  28.   

    > 线程中间有一个return -1;没有LeaveCriticalSection():(考点一 )
    这点确实记不清楚了> 线程应该为static(考点二)
    > 利用class的构造和析构调用Enter...和Leave...(临界区)(考点三)
    当时我也只看出了这2点
      

  29.   

    class MyClass
    {
            static const CRITICAL_SECTION m_CriticalSection;
    }
    如何初始化m_CriticalSection?强制类型转换?
      

  30.   

    我觉得代码中解决不了对
    构造 多个 MyClass 对象时所碰到的问题:从而导致对g_CriticalSection的访问冲突,其冲突结果大家也都看得出来.而且有可能导致g_CriticalSection占用内存的释放问题.
      

  31.   

    CRITICAL_SECTION g_CriticalSection;
    char *g_string=NULL;
                                                                                                                   
    class MyClass
    {
    public:
            int InitInstance();
            static int threadA();
    };
                                                                                                                   
    int MyClass::Init()
    {
            InitCriticalSection(&g_CriticalSection);
            CreateThread(threadA,...);
    }
                                                                                                                   
    int MyClass::threadA()
    {
            EnterCriticalSection(&g_CriticalSection)
        try{  
          if(g_string!=NULL)
            {
                    delete [] g_string;
            }
            g_string = new char[1024];
            ...
            delete [] g_string;
            g_string = NULL;
       }
      catch(...)
       {
         LeaveCriticalSection(&g_CriticalSection);
        return -1;
        }
            LeaveCriticalSection(&g_CriticalSection);
            return 0;
    }
    int MyClass::~myclass()
    {
       DeleteCriticalSection(&g_CriticalSection);
    }
      

  32.   

    也可把关键段作为class的protected用。
      

  33.   

    哪位高手解释一下在多个对象初始化时,均执行
    InitCriticalSection(&g_CriticalSection);
    会有什么后果,我觉得这个初始化只需要一次。
      

  34.   

    在初始化临界区资源并使用以后 ,没有调用DeleteCriticalSection()函数释放对象,而且它的ExitCriticalSection()函数好像应该是LeaveCriticalSection()
      

  35.   

    有ExitCriticalSection这个函数吗,好像视Leave吧
      

  36.   

    static int MyClass::threadA()
    {
    ..............
    }
    下面这样可以吗?
    g_string = NULL;
      

  37.   

    我也去了
      没有看出static的问题。  另外关于继承和构造也考了不少。 建议大家看看inside c++ .  后来看了effective c++都明白了。 算是交了学费了。 
      

  38.   

    g_CriticalSectiony应该只初始化一次。
      

  39.   

    大家可能都在找错误,忘记回答问题了,我来试写一下.
    char *g_string=NULL;class MyClass::InitCriticalSection(&g_CriticalSection)//这里我加的
    {
            static const CRITICAL_SECTION m_CriticalSection;
    public:
            MyClass() { EnterCriticalSection(m_CriticalSection); }
            ~MyClass(){ ExitCriticalSection(m_CriticalSection); }
    };下面就当是实现吧int MyClass::Init()
    {
            CreateThread(threadA,...);
    }
                                                                                                                   
    int MyClass::threadA()
    {
            if(g_string!=NULL)
            {
                    delete g_string;
            }
            g_string = new char[1024];
            ...
            delete g_string;
            g_string = NULL;
            return 0;
    }