10

I'm trying to determine the size of an object at runtime. sizeof doesn't work because this returns the size at compile time. Here is an example of what I mean:

class Foo 
{
public:
    Foo() 
    {
        c = new char[1024*1024*1024];
    }
    ~Foo() 
    { 
        delete[] c; 
    }

private:
    char *c;
};

In this case, sizeof(Foo) will be 4 bytes and not ~1GB. How can I determine the size of Foo at runtime? Thanks in advance.

icecrime
  • 74,451
  • 13
  • 99
  • 111
Dr. Jay
  • 103
  • 1
  • 6
  • 1
    possible duplicate of [If free() knows the length of my array, why can't I ask for it in my own code?](http://stackoverflow.com/questions/2650895/if-free-knows-the-length-of-my-array-why-cant-i-ask-for-it-in-my-own-code) – Greg Hewgill Dec 22 '10 at 21:35
  • 2
    You might want to distinguish the size of the object from the amount of memory controlled by the object. The allocation that you're setting `c` to point to will *never* be part of the object itself. Objects of class `Foo` will all be the same size (which will be the size of a data pointer in the example above). This is a little pedantic, but ... – dmckee --- ex-moderator kitten Dec 22 '10 at 21:37
  • `sizeof doesn't work because this returns the size at compile time.` - actually not. Sometimes there are a runtime sizeofs, especially in C99 and GCC. ( http://stackoverflow.com/questions/2615203/is-sizeof-in-c-evaluated-at-compilation-time-or-run-time/2709634#2709634 ) – osgx Dec 22 '10 at 21:54
  • possible duplicate of [How does delete\[\] "know" the size of the operand array?](http://stackoverflow.com/questions/197675/how-does-delete-know-the-size-of-the-operand-array) – fredoverflow Dec 22 '10 at 23:56
  • Just use a `std::vector` and concentrate on more interesting problems ;) – fredoverflow Dec 22 '10 at 23:58
  • 1
    @Dr. Jay, offtopic, but I wonder if you know what will happen if you try to run the following code: Foo a; Foo b = a; – StackedCrooked Dec 23 '10 at 01:32

3 Answers3

7

The size of Foo is constant. The ~1GB of chars does not technically belong to the object, just the pointer to it does. The chars are only said to be owned by the object, because the object is responsible for allocating and deallocating memory for them. C++ does not provide features that allow you to find out how much memory an object has allocated. You have to keep track of that yourself.

Oswald
  • 31,254
  • 3
  • 43
  • 68
6

You need to keep track of it yourself somehow. For example:

struct Foo 
{
    Foo()
        : elements(1024 * 1024 * 1024) 
    {
        c.reset(new char[elements]);
    }

    boost::scoped_array<char> c;
    int elements;
};

Note that you should use a smart pointer container for managing dynamically allocated objects so that you don't have to manage their lifetimes manually. Here, I've demonstrated use of scoped_array, which is a very helpful container. You can also use shared_array or use shared_ptr with a custom deleter.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • This is a great answer. However, I'm attempting to determine the memory usage of objects that I haven't written myself. Specifically, stl string, stl wstring and ICU UnicodeString all populated with the same data. Each have functions that return the size of the internal buffer but not the size of the whole object. Complicating the problem, these objects could contain pointers to other data. Any ideas? – Dr. Jay Dec 23 '10 at 16:03
  • @Dr. Jay: You can estimate, but that's about the best you can do. For a `std::string` or a `std::wstring`, you can get `s.size()` to find the size of the buffer they have (note that it's in characters, so you'll have to multiply the result for `wstring` by `sizeof(wchar_t)` to get the size in bytes) and add it to the size of the object `sizeof(s)`. For other types, you'll have to find whether they expose the size of what they contain. Anyway, it's just an estimate, since the underlying buffer(s) may be larger (e.g., for `vector`, `v.capacity()` may be greater than `v.size()`). – James McNellis Dec 23 '10 at 16:36
1

The size of the object is 4 bytes on your system. The object, however, uses additional resources, such as 1GB of memory.

Arafangion
  • 11,517
  • 1
  • 40
  • 72