0

I was wondering if there was a way to pad an object after instantiation. Say an object instantiated from class Foo with the implementation below:

class Foo
{
    size_t addr;
    unsigned allocationNum;

public:
    Foo()
    {
        addr = (size_t)this;
        allocationNum = 0;
    }

    ~Foo()
    {
        addr = 0;
        allocationNum = 0;
    }

    void SetAllocNum(unsigned nAllocationNum)
    {
         allocationNum = nAllocationNum;
    }

    unsigned GetAllocNum() const
    {
        return allocationNum;
    }

    size_t GetAddress() const
    {
        return addr;
    }
};

The instance of the object then is created through Foo* object = new Foo();. Is there a way to say add to the object so that (size_t)object or sizeof(*object) shows it as a bigger object? Also when say casting a standard data type like char* to this object is there a way to pad that cast to make the char* fit the size of the object it is casting to? I ask these questions somewhat out of curiosity and because I feel it may solve a problem I have with my program. Here is the specific context:

T* AddObject()
{
   T* object = new T(); // Here is the new object T=Foo in this case.
   *(T*)(buffer+position) = *object; // Being stored in a char* buffer at current empty position
   T* returnValue = &(*(reinterpret_cast<T*>(buffer+position))); 
   //  ^ Here I try casting the char* buffer@position with the object contents stored inside the buffer.
   return returnValue;
}

Problem with this is that it is casting it to a T object somewhat decently but the size is still that of the buffer. Performing sizeof(*object) in main will display what I think size of the object should be but if I compare the (size_t) object from Foo* object = new Foo() with the (size_t)differentObj from Foo* differentObj = AddObject() the (size_t)differentObj will be the the same as (size_t)buffer but not the same as (size_t)object. Maybe its because I don't understand what size_t is representing differently than sizeof whether its the number of bits the objects in memory have or not I'm not sure. At least from what I understand sizeof represents the amount of memory in bytes that a variable or type occupies.

  • Is this your idea for how to serialize objects to/from memory buffers, and eventually (potentially) over/through other mediums? I ask because (a) there are *much* better ways, and (b) If you're interested in constructing an object in a self-managed memory buffer, I suggest you research the [placement-new idiom](http://stackoverflow.com/questions/222557/what-uses-are-there-for-placement-new). Regardless, objects are type-defined with specific static size. You cannot change that definition at run-time. But you can contain members that use heap-management for growth (ex: a vector). – WhozCraig Sep 11 '13 at 08:23
  • @WhozCraig well I tried doing serialization through Boost but the problem with boost was I needed control of the object declaration to give access for boost to serialize. Atm I can't touch where the Object declaration/definition is so I had to come up with this workaround. Plus I prefer using vectors for container implementations but I was restricted from doing so in this program. Thank you because you and the others suggestions helped point me toward the right direction. Also I couldn't avoid sending back a pointer of the object so would serialization not help me in this case? – hellfiremarine Sep 11 '13 at 23:08

2 Answers2

1

Do you realize that (size_t)object is not giving you any size, but that this is a (c-style) cast of object to the type size_t (usually defined as unsigned int)? See e.g. this size_t documentation. sizeof (see e.g. its documentation here) returns a value of type size_t, probably that's where your confusion about it comes from?

You probably want to use sizeof all the time. Be careful about what you pass in to sizeof, though. sizeof(Foo*) for example will give you the size of a pointer to Foo, not the size of the Foo object. For the latter you'd have to use sizeof(Foo).

(sizeof)x is evaluated at compilation time, and calculated via the type definition; in the case that x is a user defined type, that is by the struct or class interface. So there is no way to change the outcome of sizeof, apart from changing the interface.

codeling
  • 11,056
  • 4
  • 42
  • 71
  • thank you! In this scenario I would rather use sizeof for determining the size of objects but the people who wrote the code to test the container used (size_t)object and so I was trying to figure out what the (size_t)object was representing. Your suggestions gave me more insight about size_t. I would up the answer is useful but I currently don't have enough rep on this forum to do so. – hellfiremarine Sep 11 '13 at 23:12
0

If you want to construct an object at a specific address you should use placement new:

T* AddObject()
{
    return new (buffer+position) T();
}

Note that you cannot use the default delete if you use this version of new.

sizeof is a compile-time operator which will yield its value from the type. It cannot be overloaded, and the returned value is of type size_t. size_t is an unsigned integer type defined in the standard library.

When writing (size_t)differentObj you cast from T* to size_t. This is valid, but usually not something one would want to do. If you want to calculate an offset between two pointers in exact bytes you say reinterpret_cast<char*>(pointer1) - reinterpret_cast<char*>(pointer2).

When two pointers have the same value (e.g. (size_t)differentObj == (size_t)buffer) it means that they point to the same object. (This means that position must be set to 0 in your example.)

Anyway, you should only use these techniques if you really need to, because pointer fiddling complicates the code a lot.

Hilborn
  • 755
  • 9
  • 14
  • thank you! The placement new worked for solving the problem I had. Usually I prefer to use sizeof() operator when comparing objects but I was restricted in this program to use (size_t). Also I like using more robust STL containers for container storage such as vectors but was restricted to using a char* buffer to store the objects. Plus I would upvote usefulness of this answer but I don't quite have enough reputation on this forum yet to do so. – hellfiremarine Sep 11 '13 at 23:17