C++ Xerces-c:初始化shared_ptr

发布于 2024-10-11 11:27:01 字数 829 浏览 7 评论 0原文

我是共享指针的新手,想知道如果共享指针也是成员变量,如何初始化它?

目前我的代码看起来像这样: 在头文件中,我有:

class Parser {
   public:
      Parser();
      ~Parser();

      boost::shared_ptr<XercesDOMParser> parser;
{

在构造函数中,我有这样的内容:

Parser::Parser() 
{
   try {
      XMLPlatformUtils::Initialize(); 
   } catch (...) {}

   parser = shared_ptr<XercesDOMParser> (new XercesDomParser()); 
}

在析构函数中,我有:

Parser::~Parser() {
   try {
      XMLPlatformUtils::Terminate();
   }catch(...) {}
}

但是,使用 Valgrind 编译程序时,我会收到以下错误: 纯虚方法调用。 无活动异常而终止。 大小 8 的读取无效。

对于我在初始化过程中可能做错了什么有什么见解吗?

我怀疑我正在从未分配的内存中读取数据。

编辑:

所以在析构函数中,我在终止命令之前添加了以下代码行,内存泄漏和错误都消失了!

如果(解析器) 解析器.reset();

为什么对解析器的所有引用都必须消失才能释放?

非常感谢,谢谢。

I am new to shared pointers and was wondering how to initalize a shared pointer if it is also a member variable?

Currently my code looks something like this:
In the header file, I have:

class Parser {
   public:
      Parser();
      ~Parser();

      boost::shared_ptr<XercesDOMParser> parser;
{

In the constructor, I have something like this:

Parser::Parser() 
{
   try {
      XMLPlatformUtils::Initialize(); 
   } catch (...) {}

   parser = shared_ptr<XercesDOMParser> (new XercesDomParser()); 
}

In the destructor I have:

Parser::~Parser() {
   try {
      XMLPlatformUtils::Terminate();
   }catch(...) {}
}

However compiling the program with Valgrind, I would receive the following error:
Pure virtual method called.
Terminated without an active exception.
Invalid read of size 8.

Any insights into what I may be doing incorrectly with the initialization?

My suspicion is I am reading from unallocated memory.

EDIT:

So in the destructor, I added the following lines of code before the terminate command and the memory leaks and errors all disappeared!

if (parser)
parser.reset();

Why does all reference to the parser have to be gone before it can be deallocated?

Much appreciated, thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜尕妞 2024-10-18 11:27:01

您在调用 XercesDomParser 的析构函数之前调用 XMLPlatformUtils::Terminate()。成员变量的析构函数在析构函数体运行后调用。成员变量按照声明的顺序构造,并按相反的顺序销毁。

你可以这样做:

class Parser : boost::noncopyable {
    struct XmlHandle {
        XmlHandle() { XMLPlatformUtils::Initialize(); }
        ~XmlHandle() { XMLPlatformUtils::Terminate(); }
    };

    XmlHandle m_handle;
    boost::shared_ptr<XercesDOMParser> m_parser;

public:
    Parser() : m_parser(new XercesDomParser) { }
};

并且只使用默认的析构函数。如果您想要复制构造函数和赋值运算符,则需要处理它。

哦,捕获并丢弃异常可能是一个坏主意......

You are calling XMLPlatformUtils::Terminate() before calling the destructor for XercesDomParser. Destructors for member variables are called after the destructor body runs. Member variables are constructed in order of declaration, and destroyed in reverse.

You could do something like this:

class Parser : boost::noncopyable {
    struct XmlHandle {
        XmlHandle() { XMLPlatformUtils::Initialize(); }
        ~XmlHandle() { XMLPlatformUtils::Terminate(); }
    };

    XmlHandle m_handle;
    boost::shared_ptr<XercesDOMParser> m_parser;

public:
    Parser() : m_parser(new XercesDomParser) { }
};

And just use the default destructor. If you want copy constructors and assignment operators you'll need to deal with that.

Oh, and catching and throwing away exceptions is probably a bad idea ...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文