0
\$\begingroup\$

I have written below program to count the number of static and dynamically created object of the class.

#include <iostream>
class Test 
{
   public:
    Test()
    {
      stackCount++;
    }
    
    void* operator new(size_t objSize)
    {
       void* ptr = malloc(objSize);
       heapCount++;
       return ptr;
    }
    
    static void Display()
    {
      std::cout << "stack object count : " << stackCount - heapCount << ", Heap object Count :" <<  
      heapCount << std::endl;
    }
    
   private:
    static int stackCount;
    static int heapCount;
};
    
int Test::stackCount = 0;
int Test::heapCount = 0;
     
int main() 
{
    Test obj1;
    Test obj2;
    Test obj3;
       
    Test *ptr = new Test();
        
    Test::Display();
        
    return 0;
}

Program output : stack object count : 3, Heap object Count :1

is there any better way to maintain the count of static and dynamic object.?

\$\endgroup\$
3
  • \$\begingroup\$ You are actually separating dynamically-allocated full objects from anything else, be it static, automatic, or member (of a class, including lambdas, union, or array). \$\endgroup\$ Jul 20, 2022 at 18:22
  • 1
    \$\begingroup\$ I don't see where your code statically allocates anything. \$\endgroup\$ Jul 21, 2022 at 9:37
  • 2
    \$\begingroup\$ “is there any better way to maintain the count of static and dynamic object.?” It is literally impossible to do that. Your code does not do that; instead it is relying on undefined behaviour. In your custom new, you allocate the memory for the object… but never call the object’s constructor. If you did that, you would see your counts don’t work. Why do you want to count heap versus “stack” objects anyway? What’s the point? \$\endgroup\$
    – indi
    Jul 21, 2022 at 10:01

1 Answer 1

3
\$\begingroup\$

malloc is used but never defined. You probably want std::malloc, from the <cstdlib> header.

Prefer pre-increment (++i) to post-increment, if you're not using the result. For simple arithmetic types, decent compilers will optimise away the copy, but that's not possibly for more complex class types, so cultivate a good habit that can save some performance one day.

On the subject of small performance wins, don't use std::endl when there isn't a need to flush the stream (and prefer a separate std::flush even then, to keep the intention clear).

I recommend changing how you break long << lines, to make it clearer what's a continuation line even when you can't see the whole line:

      std::cout << "stack object count : " << stackCount - heapCount
                << ", Heap object Count :" << heapCount << '\n';

See how the indentation and use of << at the start help show that this is a single (logical) line?

You have a memory leak, because you never delete ptr. However, we need to implement a matching operator delete() for that to work properly.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ malloc() shouldn't be used at all. operator new() can simply call new char[objSize]. \$\endgroup\$
    – G. Sliepen
    Jul 22, 2022 at 9:33
  • 2
    \$\begingroup\$ If you use new, you need to take alignment into account. malloc() allocates at maximum alignment, so it’s not a problem there. \$\endgroup\$
    – indi
    Jul 22, 2022 at 11:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.