Gengoo 发表于 2009-3-24 16:45:22

ACE_Message_Queue中释放消息块出现异常

头文件:
MQ.h

#ifndef MQ_H_
#define MQ_H_

#include "ace/Message_Queue.h"
#include "ace/Task.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Stream.h"
#include "ace/SOCK_Connector.h"
#include "ace/Log_Msg.h"
#include "ace/Os.h"
#include "ace/Thread_Mutex.h"
#include "ace/Mutex.h"
#include "ace/Lock.h"
#include "ace/Addr.cpp"
#include "ace/Time_Value.cpp"
#include "ace/String_Base_Const.cpp"
#include "ace/OS_String.cpp"

class QTest
{
public:
        QTest(int num_msgs);

        int enq_msgs();

        int deq_msgs();

private:

        //定义消息队列
        ACE_Message_Queue <ACE_NULL_SYNCH> *mq_;

        //消息队列个数
        int no_msgs_;
};

#endif

源文件:
MQ.cpp

#include "MQ.h"

QTest::QTest(int num_msgs) : no_msgs_(num_msgs)
{
        ACE_TRACE("QTest::QTest");

        //第一次创建消息队列定义大小
        if (! (this->mq_ = new ACE_Message_Queue <ACE_NULL_SYNCH> ()))
        {
                ACE_DEBUG ((LM_ERROR, "Error in message queue initialization\n"));
        }
}

int QTest::enq_msgs()
{
        ACE_TRACE ("QTest::enq_msgs");

        for (int i=0; i<no_msgs_; i++)
        {
                //为每个消息创建一个消息块
                ACE_Message_Block *mb;

                //初始化消息块大小
                ACE_NEW_RETURN (mb, ACE_Message_Block (ACE_OS::strlen("This is message 1\n")), -1);

                //把数据插入到消息块
                ACE_OS::sprintf (mb->wr_ptr(), "This is message %d\n", i);

                //移动消息块的指针
                mb->wr_ptr (ACE_OS::strlen("This is message 1\n"));

                //把消息块入队
                if (this->mq_->enqueue_prio (mb) == -1)
                {
                        ACE_DEBUG ((LM_ERROR, "\nCould not enqueue on to mq!!\n"));

                        return -1;
                }

                ACE_DEBUG ((LM_INFO, "EQ'd data: %s\n", mb->rd_ptr() ));
        }

        //现在打印所有的消息
        this->deq_msgs();

        return 0;
}

int QTest::deq_msgs()
{
        ACE_TRACE ("QTest::dequeue_all");

        ACE_DEBUG ((LM_INFO, "No. of Messages on Q: %d Bytes on Q: %d\n",
                mq_->message_count(), mq_->message_bytes()));

        ACE_Message_Block *mb;

        for (int i=0; i<no_msgs_; ++i)
        {
                mq_->dequeue_head(mb);

                ACE_DEBUG ((LM_INFO, "DQ'd data %s\n", mb->rd_ptr()));

        //        mb->rd_ptr(ACE_OS::strlen(mb->rd_ptr()) + 1);

                mb->release();   //在这里释放的时候就抛异常了。
        }

        return 0;
}

int main(int argc, char *argv[])
{
        if (argc < 2)
        {
                ACE_ERROR_RETURN ((LM_ERROR, "Usage %s num_msgs", argv), -1);

        }

        QTest test (ACE_OS::atoi(argv));

        if (test.enq_msgs() == -1)
        {
                ACE_ERROR_RETURN ((LM_ERROR, "Program failure\n"), -1);
        }

        return 0;
}

每次在我调试时, 在mb->release(); 抛出异常了

EQ'd data: This is message 0

EQ'd data: This is message 1

EQ'd data: This is message 2

EQ'd data: This is message 3

EQ'd data: This is message 4

No. of Messages on Q: 5 Bytes on Q: 90
DQ'd data This is message 0

这是为啥啊

Gengoo 发表于 2009-3-24 17:19:07

怎么就没人给我看一下这个问题的原因啊

modern 发表于 2009-3-24 17:23:55

先看内存信息呀,你先打断点,执行到那里 mb里面到底是什么值,mq_产生了什么变化。
看你的日志输出,mb->rd_ptr()返回值是0,你release当然会崩溃了。

Gengoo 发表于 2009-3-24 17:40:04

不是你说的:mb->rd_ptr()返回值0。 它的返回值是:This is message is 0,
同时我也看了mb的信息:在内在中的地址是0x00982c30,
当运行到mb->release()之前, 都正确啊, 就是这句后, 就造成了程序崩溃.

如果我把mb->release()注销掉, 它就能正常输出结果。
EQ'd data: This is message 0

EQ'd data: This is message 1

EQ'd data: This is message 2

EQ'd data: This is message 3

EQ'd data: This is message 4

No. of Messages on Q: 5 Bytes on Q: 90
DQ'd data This is message 0

DQ'd data This is message 1

DQ'd data This is message 2

DQ'd data This is message 3

DQ'd data This is message 4

Press any key to continue

但是如果注销, 不就造成了内存泄露吗。

modern 发表于 2009-3-24 18:16:38

刚才确实我看错了,release的用法没什么问题,不过下面这段代码看起来好像有问题。
//初始化消息块大小
ACE_NEW_RETURN (mb, ACE_Message_Block (ACE_OS::strlen("This is message 1\n")), -1);

初始化的时候把长度设置大一些试一下。
ACE_NEW_RETURN (mb, ACE_Message_Block (20),-1);

Gengoo 发表于 2009-3-25 13:50:51

非常谢谢啊, 果然是分配内存的时候出了问题,

按照你的改了后就没问题了

gunwithrose 发表于 2009-4-3 16:57:27

ACE_NEW_RETURN (mb, ACE_Message_Block (ACE_OS::strlen("This is message 1\n") +1), -1);

就可以了!!
页: [1]
查看完整版本: ACE_Message_Queue中释放消息块出现异常