标题:怪事年年有,今年特别多啊。。。调试的问题……
只看楼主
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
结帖率:100%
 问题点数:0 回复次数:6 
怪事年年有,今年特别多啊。。。调试的问题……
我做个程序,有时在Debug下正常运行,在Release下屡屡出错。有时却又反过来……
但是我在某个关键部位加了个MessageBox后又没事了,可我总不可能拉着MessageBox不放吧?
大家有什么好的调试经验,能启发一下我好吗?
搜索更多相关主题的帖子: 怪事 调试 MessageBox Release Debug 
2008-03-07 17:36
余来
Rank: 6Rank: 6
等 级:贵宾
威 望:26
帖 子:956
专家分:18
注 册:2006-8-13
得分:0 
我估计楼主是做的一个DirectX引擎的东东,如果是,建议你马上去看看你释放DirectX接口时的顺序吧,释放接口顺序必须和创建顺序相反,错一个都不行,不然总是摸名奇妙的内存错误

2008-03-07 17:46
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
得分:0 
嘿嘿,果然不愧是版主,的确了解我在做什么。
真是知我者,余来也。

天之道,损有余而补不足.人之道则不然,损不足以奉有余.孰能有余以奉天下,唯有道者.
2008-03-08 13:31
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
得分:0 
我发现new虽然好用,但是却很容易忘记释放,
有时内存泄露调试的时候不会提示,
还有就是下标越界的问题,这方面VC没VB好。

天之道,损有余而补不足.人之道则不然,损不足以奉有余.孰能有余以奉天下,唯有道者.
2008-03-08 13:41
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
得分:0 
释放一个类的指针是用delete[]还是delete?
他们具体怎么使用?有些书说的好象有问题……
还有什么其他的释放内存的函数?

天之道,损有余而补不足.人之道则不然,损不足以奉有余.孰能有余以奉天下,唯有道者.
2008-03-08 13:45
yuki
Rank: 2
等 级:新手上路
威 望:5
帖 子:508
专家分:0
注 册:2005-2-4
得分:0 
new好用忘记释放的情况在大项目中非常常见,这需要好的设计模式的思想支持。

建议使用工厂模式(具体参考设计模式书籍或文献)
下面简单说下方法:
建个工厂物件(FactoryObj)作为接口,将该工厂的默认构造函数设为保护类型,只需要需要提供一个方法,也就是创建实例,请看简单的代码。
程序代码:
class IFactoryObj
{
protected:
    FactoryObj() {}
protected:
    static void *createInstance(const char *pDataType);
};
// 根据不同的数据类型提示,进行实例的生成,并且封箱
// 举个例子,比如说有具体类A,需要用工厂生成
void *FactoryObj::createInstance(const char *pDataType)
{
    if(!strcpy(pDataType, "Class_A"))
        return (void *)(new A);
    else
        return NULL;
};

然后我们需要建一个A对象的具体工厂,通过继承上面提供的抽象工厂接口,工厂A无需继承,为了全局使用将其构造函数设为私有。
程序代码:
class FactoryA : public IFactoryObj
{
private:
    FactoryA() {}
public:
    static A *getInstance(); //这个函数就可以生成一个A对象的实例
    static void ungetInstance(A *objA); // 这个函数用来撤销一个A对象的分配
};

// 这里我们实现这两个函数
A *FactoryA::getInstance()
{
    return (A *)createInstance("Class_A");
}

void FactoryA::ungetInstance(A *objA)
{
    if(objA)
        delete A;
}

好了,假设我们有B对象需要使用A对象指针作为成员,并且要在构造时新建,则
程序代码:
class B
{
public:
    B();
    virtual ~B(); // 开发提示,请不要在析构函数中直接书写大量的清理代码
protected:
    virtual void dispose(); // 注意这个函数作为回收使用,虚方法使其派生后实现不同的清理方法
protected:
    A *m_pA;
};
// 实现构造
B::B()
{
    // 我们要为A对象分配空间
    m_pA = FactoryA::getInstance(); // 好了,从工厂获得实例,不用担心数据类型的转换,因为他是属于A对象的工厂,所以工厂中的流水线只生产A。
}

// 实现析构
B::~B()
{
    // 调用清理函数,好处是继承以后可以实现不同的清理效果
    dispose();
}

// 实现清理函数
void B::dispose()
{
    // 通过工厂销毁A对象,也就是客户将用旧的东西重新送回工厂进行销毁
    FactoryA::ungetInstance(m_pA);
    // 别忘了把指针置空,防止非法访问时内存违例
    m_pA = NULL;
}

我刚才说到的虚清理函数,另一个好处便是,不仅可以进行派生类的正确清理,而且可以调用基类的清理还属,进行逐层的清理,这样就不会有遗漏了,这种方法请参见设计模式的修饰(decorate)模式

[[it] 本帖最后由 yuki 于 2008-3-17 16:05 编辑 [/it]]

我们都在命运湖上荡舟划桨,波浪起伏使我们无法逃离孤行;如果我们迷失方向,波浪将指引我们穿过另一天曙光
2008-03-17 16:04
sunkaidong
Rank: 4
来 自:南京师范大学
等 级:贵宾
威 望:12
帖 子:4496
专家分:141
注 册:2006-12-28
得分:0 
不错的方法..自动清理....我也遇到debug正确..release错误的情况了..收藏了

学习需要安静。。海盗要重新来过。。
2008-03-17 16:15



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-202399-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.409034 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved