清除栈错误: User 42 panic

来源:互联网 发布:mysql 导出文件格式 编辑:程序博客网 时间:2024/06/15 08:21

A C class, CSquare, uses multiple inheritance from CBase and an M class interface, MPolygon. The object is instantiated and the M class interface pushed on to the cleanup stack. The object is later destroyed by a call to PopAndDestroy(). If the pushing was done with CleanupStack::PushL(), the PushL(TAny*) would be used because the pointer is not a CBase pointerThe PushL(TAny*) overload means that User::Free() is invoked on the pointer on cleanup, but this would result in a User 42 panic. That’s because User::Free() can't find the heap information it needs to release the memory to the system when passed an M class pointer to the sub-object of a C class. Even if it could, the virtual destructor of CSquare would not be called, so the best-case scenario would be a memory leak! The solution is to use CleanupDeleteL() to call delete on the M class pointer and invoke the virtual destructor correctly for the CSquare class.

对于同时继承了cbase和m接口的类,如果使用pushL(),将会重载 PushL(TAny*) ,这就意味着异常退出会调用User::Free() 来清除,但free()不能找到内存中需要释放的信息,析构函数不能被调用,从而引发User 42 panic.解决方案就是使用CleanupDeleteL() t来调用m类指针的删除操作以及cbase析构函数。


class MPolygon
    {
 
public:
 
    virtual TInt CalculateNumberOfVerticesL() =0;
    virtual ~MPolygon(){};
 
};
 
class CSquare : public CBase, public MPolygon
    {
public:
    static CSquare* NewL();
    virtual TInt CalculateNumberOfVerticesL();
    virtual ~CSquare(){};
 
private:
    CSquare(){};
 
    };
 
enum TPolygonType { ESquare };
 
static MPolygon* InstantiatePolygonL(TPolygonType aPolygon);
 
MPolygon* InstantiatePolygonL(TPolygonType aPolygon)
    {
    if (ESquare==aPolygon)
        return (CSquare::NewL());
    else
        return (NULL);
    }
 
/*static*/ CSquare* CSquare::NewL()
    {              // No two-phase construct needed here.
    CSquare* me = new(ELeave) CSquare();
    return (me);
    }
 
TInt CSquare::CalculateNumberOfVerticesL()
    {             // Simple implementation, but others may leave.
    return (4);
    }
 
void DoStuffL()
    {
    MPolygon* square = InstantiatePolygonL(ESquare);
    CleanupDeletePushL(square);
 
    // ... Leaving calls go here.
    ASSERT(4==square->CalculateNumberOfVerticesL());
    CleanupStack::PopAndDestroy(square);
    }

原创粉丝点击