Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7699697
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T22:32:20+00:00 2026-05-31T22:32:20+00:00

Manual Unref I have an issue with Boost’s intrusive pointer. It’s boolean conversion operator

  • 0

Manual Unref

I have an issue with Boost’s intrusive pointer. It’s boolean conversion operator checks x.get() != 0. However, the code below fails at the marked point. Why is this the case?

I am guessing that I may have to do with the fact that delete does not set a pointer to 0 (or nullptr). If that’s not the case, how could I use the intrusive pointer effectively? I would like to be able to use an intrusive pointer like a regular pointer, e.g., in an expression x && x->foo(), but this artefact seems to preclude it.

#include <atomic>
#include <boost/intrusive_ptr.hpp>

struct T
{
    T() : count(0u) { }

    size_t ref_count()
    {
        return count;
    }

    std::atomic_size_t count;
};

void intrusive_ptr_add_ref(T* p)
{
    ++p->count;
}

void intrusive_ptr_release(T* p)
{
    if (--p->count == 0u)
        delete p;
}

int main()
{
    boost::intrusive_ptr<T> x;
    x = new T;
    assert(x->ref_count() == 1);

    auto raw = x.get();
    intrusive_ptr_add_ref(raw);
    intrusive_ptr_add_ref(raw);
    assert(x->ref_count() == 3);

    intrusive_ptr_release(raw);
    intrusive_ptr_release(raw);
    assert(x->ref_count() == 1);

    intrusive_ptr_release(raw); // Destroys T, ref_count() == 0.
    assert(! x); // Fails.

    return 0;
}

(Architecture: Darwin 10.7, tested compilers g++ 4.7 and 4.6 with -std=c++11)

Reference-to-Pointer

After weeding through the source code of intrusive_ptr<T>, I found that there is only one call to intrusive_ptr_release in the destructor:

~intrusive_ptr()
{
    if( px != 0 ) intrusive_ptr_release( px );
}

Since the argument px of type T* is an lvalue, it should be possible to set it to zero by slightly changing the function signature of intrusive_ptr_release:

inline void intrusive_ptr_release(T*& p)
{
    if (--p->count == 0u)
    {
        delete p;
        p = 0;
    }
}

Intuitively, this pointer reference-to-pointer parameter should assign the lvalue of p in the calling context to 0. Bjarne also mentions this idiom. However, the assertion still fails at the marked line, leaving me clueless this time.

Example Usage

The reason why I am ref’ing and unref’ing the pointer manually is that I have to work with the raw pointer for a while when passing it to a C API. This means I have to ref it before passing it to the C API in order to prevent destruction, and recreate an intrusive pointer from the raw pointer when I get it back. Here is an example:

void f()
{
    intrusive_ptr<T> x = new T;
    auto raw = x.get();
    intrusive_ptr_add_ref(raw);
    api_in(raw);
}

void g()
{
    T* raw = api_out();
    intrusive_ptr<T> y(raw, false);
    h(y);
}

Here, the second parameter in the construction of y in g() avoids a ref when getting the pointer back from the C API, which compensates for the manual ref in f().

I realized that manually unreffing an intrusive pointer can lead to unexpected behavior, whereas this usage appears to be fine.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T22:32:21+00:00Added an answer on May 31, 2026 at 10:32 pm

    The question is: Why do you expect x to convert to false at the end? You’re messing with the ref counter in unexpected ways! You’re decreasing it to zero even though there is still an intrusive_ptr — x — that points to the object. That’s not how it works. The ref counter is supposed to be at least as great as the number of intrusive_ptr objects that point to the ref counted object — otherwise it would not be a ref counter, would it?

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

The manual doesn't have an example how to use db.allocate_id_range. I tried some code
http://php.net/manual/en/mysqli.init.php $ConnectionResource = mysqli::init(); The above code fails with: Fatal error: Non-static method mysqli::init()
gdb manual says the following. Warning: In multi-threaded programs, software watchpoints have only limited
In the boost::proto manual, there is an example of a grammar that matches terminals
(Assuming manual enlistment and delistment of resources.) I have a number of XA enabled
So I have a manual in this table: id lang header_name text 1 uk
PHP manual says you have to do sort($array) . $array will be passed by
GCC manual says: file.m      Objective-C source code. Note that you must link with
The manual at http://couchapp.org/page/couchapp-config says that you can store passwords in ~/.couchapp.conf . However,
Having read Completely manual Mercurial merge , I have such a .hgrc : [ui]

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.