Search code examples
c++structurepointer-arithmetic

Deallocate structure using pointer arithmetics and a pointer to an element of that structure


I have the following structure in C++ :

struct wrapper 
{
    // Param constructor
    wrapper(unsigned int _id, const char* _string1, unsigned int _year, 
         unsigned int _value, unsigned int _usage, const char* _string2)
         :
         id(_id), year(_year), value(_value), usage(_usage)
         {
             int len = strlen(_string1);
             string1 = new char[len + 1]();
             strncpy(string1, _string1, len);

             len = strlen(_string2);
             string2 = new char[len + 1]();
             strncpy(string2, _string2, len);
         };
    // Destructor
    ~wrapper()
         {
             if(string1 != NULL) 
                delete [] string1;
             if(string2 != NULL) 
                delete [] string2;
         }

    // Elements
    unsigned int     id;         
    unsigned int     year;       
    unsigned int     value;     
    unsigned int     usage; 
    char*            string1;    
    char*            string2;   
};

In main.cpp let's say I allocate memory for one object of this structure :

wrapper* testObj = new wrapper(125600, "Hello", 2013, 300, 0, "bye bye");

Can I now delete the entire object using pointer arithmetic and a pointer that points to one of the structure elements ?

Something like this :

void*  ptr = &(testObj->string2);

ptr -= 0x14;

delete (wrapper*)ptr;

I've tested myself and apparently it works but I'm not 100% sure that is equivalent to delete testObj.

Thanks.


Solution

  • Can I now delete the entire object using pointer arithmetic and a pointer that points to one of the structure elements ?

    Theoretically, yes.

    The pointer that you give to delete needs to have the correct value, and it doesn't really matter whether that value comes from an existing pointer variable, or by "adjusting" one in this manner.

    You also need to consider the type of the pointer; if nothing else, you should cast to char* before performing your arithmetic so that you are moving in steps of single bytes. Your current code will not compile because ISO C++ forbids incrementing a pointer of type 'void*' (how big is a void?).

    However, I recommend not doing this at all. Your magic number 0x14 is unreliable, given alignment and padding and the potential of your structure to change shape.

    Instead, store a pointer to the actual object. Also stop with all the horrid memory mess, and use std::string. At present, your lack of copy constructor is presenting a nasty bug.