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

  • Home
  • SEARCH
  • 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 3433324
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T07:33:35+00:00 2026-05-18T07:33:35+00:00

I’m working on a small memory tool which tracks allocations and deallocations, object sizes,

  • 0

I’m working on a small memory tool which tracks allocations and deallocations, object sizes, object types, and so on. The method I’m using to track source files, line numbers, and object types works like this:

#define DEBUG_NEW SourcePacket(__FILE__, __LINE__) * new
#define new DEBUG_NEW

SourcePacket is just a small class which takes a const char* and an int during construction. These values are populated via the __FILE__ and __LINE__ macros. The object type is acquired like so:

template<typename T>
T* operator*(const SourcePacket& packet, T* p);

p is the pointer to the newly allocated object, the type of which is discovered using RTTI. In the operator overload, the information is taken and stored in the tracer and the pointer is passed on to the program. Further info like the size and address is grabbed in the overloaded operator new.

Now, this setup has worked very well for me. It doesn’t work for code which I don’t compile, naturally, but one of the best things is that it plays nice with placement new calls made by the user, which didn’t work using the oft-cited

#define new new(__FILE__, __LINE__)

method. The problem I’ve encountered is that if the user calls operator new, the program simply can’t compile. Of course, this is because the macro expands like so

return operator SourcePacket("blahblah.cpp", 20) * new(size);

instead of

return SourcePacket("blahblah.cpp", 20) * new(size);

I can’t really see any way around this. I could, of course, just remove the SourcePacket * new procedure and just let my overloaded operator new collect the size and address, but that kind of defeats a large portion of the purpose of the tool.

(Also, just as a note, I’m not trying to create Valgrind or anything, and I know that overloading the global ops can be rather dodgy. This is mostly for educational purposes. In addition, I know that OS-specific features can be used to discover some of this information, but I would only like to use standard C++ in order for it to be cross-platform and bit-independent (x86, x64, etc.). So far it’s worked flawlessly for me on both Linux and Windows releases of both bit-flavors.)

Unfortunately, there doesn’t seem to be any way to conditionally use one way or the other, depending on if it’s just new (or placement new) or operator new. It’s not critical that I get this to work, but I would be interested to hear if anyone has found a way around this limitation.

  • 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-18T07:33:36+00:00Added an answer on May 18, 2026 at 7:33 am

    We need an expression that’s valid when prefixed with “operator” and when not. This means we need to define an operator that takes a SourcePacket. It could take other arguments, but it turns out this isn’t necessary. Unary operator * will do nicely:

    const SourcePacket& operator *(const SourcePacket& sp)  {
        return sp;
    }
    
    #define DEBUG_NEW *(SourcePacket(__FILE__, __LINE__)) * new
    #define new DEBUG_NEW
    

    Since we can’t fully parenthesize the statement, there’s still the possibility of errors if used in all but the simplest expressions.

    struct Chain {
      Chain() : next(0) {}
      Chain(Chain *n) : next(n) {}
      ~Chain() {delete next;}
      Chain* next; 
      Chain& operator *(Chain* b);
    };
    Chain& Chain::operator *(Chain* b) { 
       if (b != next) {
         if (next) { delete next; }
         next = b;
       }
       return *this; 
    }
    
    int main() {
      Chain fetters;
      /* since * is left associative, it tries to 
         call operator*(Chain&, const SourcePacket&)
         */
      fetters * new Chain();
      // This compiles
      fetters * (new Chain());
    }
    

    To resolve this, we need to define the appropriate operator. For the return type, you could define a hierarchy of template classes that pair a left argument with a SourcePacket and are commutative in the right argument ((a:A ⊙ b:SourcePacket) * c:C) = (a:A ⊙ c:C) * b:SourcePacket, where ⊙ is some binary C++ operator). Something like the following, but without the bugs it undoubtedly possesses.

    template <typename L, typename Rslt=L, typename R=const SourcePacket> 
    struct PairedTraits {
        typedef L Left;
        typedef R Right;
        typedef Rslt Result;
        typedef PairedTraits<Result> ResultTraits;
    };
    
    template <typename L, typename Traits = PairedTraits<L> >
    struct Paired {
        typedef typename Traits::Left Left;
        typedef typename Traits::Right Right;
        typedef typename Traits::Result Result;
        typedef Paired<typename Traits::Result, typename Traits::ResultTraits> ResultPaired;
    
        Left& left;
        Right& right;
    
        Paired(Left& l, Right& r) : left(l), right(r) {} 
        operator Left&() {return left;}
    
        template <typename A>
        ResultPaired  operator*(const C& c) const
        {return ResultPaired(this->left * c, this->right); }
    };
    
    template <typename L, typename Traits = PairedTraits<L> >
    struct MultPaired : Paired<L, Traits> {
        typedef Paired<L, Traits> Base;
        typedef Paired<typename Traits::Result, typename Traits::ResultTraits> ResultPaired;
    
        MultPaired(typename Traits::Left& l, typename Traits::Right& r) : Base(l, r) {} 
    
        template <typename A>
        ResultPaired  operator*(const C& c) const
        {return ResultPaired(this->left * c, this->right); }
    };
    
    template <typename L, typename Traits = PairedTraits<L> >
    struct ModPaired : Paired<L, Traits> {
        typedef Paired<L, Traits> Base;
        typedef Paired<typename Traits::Result, typename Traits::ResultTraits> ResultPaired;
    
        ModPaired(typename Traits::Left& l, typename Traits::Right& r) : Base(l, r) {} 
    
        template <typename A>
        ResultPaired operator*(const C& c) 
        {return ResultPaired(this->left % c, this->right); }
    };
    
    template <typename L, typename Traits = PairedTraits<L> >
    struct DivPaired : Paired<L, Traits> {
        typedef Paired<Traits> Base;
        typedef Paired<typename Traits::Result, typename Traits::ResultTraits> ResultPaired;
    
        DivPaired(typename Traits::Left& l, typename Traits::Right& r) : Base(l, r) {} 
    
        template <typename A>
        ResultPaired operator*(const C& c) const
        {return ResultPaired(this->left / c, this->right); }
    };
    

    The children of Paired could return a Result (left ⊙ c, or left ⊙ (right * c), which basically makes *(const SourcePacket&, T) right associative) rather than a Paired. For example:

    template <typename L, typename Traits = PairedTraits<L> >
    struct DivPaired : Paired<L, Traits> {
        typedef Paired<L, Traits> Base;
    
        MultPaired(typename Traits::Left& l, typename Traits::Right& r) : Base(l, r) {} 
    
        template <typename A>
        Result  operator*(const C& c) const
        {return this->left / (this->right * c); }
    };
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

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.