0

What I am trying to do is to place a class object in the buffer and then be able to reference it correctly later.Essentially its a container class using a buffer for data storage.The best way I thought of doing so was storing the object's address in the buffer, reference it by its index, and then cast it. I see now by doing it that way can potentially leave memory leaks because the object is only living locally in this method and the address of that local object is being returned. Is there a way I can store the object into the buffer and have it correctly referenced later by invoking overloaded operator[] Foo[index]? I have tried using the same technique with C++: Casting an Object to char* for saving/loading but static/re-interpret cast in my case are tending to change the address values when I attempt to do an address look up for the contents in the buffer.

ps. I know that using a vector would be an easier way of storing class objects but part of the restriction is that I can't use STL for data storage and have to rely on the buffer given to me.

#include <stdlib.h>
#include <assert.h>
#ifndef FOO_H_
#define FOO_H_

template <typename T>
class Foo {
    char * oBuffer = NULL;
    unsigned items = 0, bSize = 0;
public:
    Foo(char * pBuffer, unsigned nBufferSize) :
        oBuffer(pBuffer),
        items(),
        bSize(nBufferSize){

        /*for (unsigned i =0; i < nBufferSize; i++)
            oBuffer[i] = &pBuffer[i];*/
    }
    ~Foo(){ delete[] oBuffer;}

    T * Add(){              ///======   Adds an element to the container, constructs it and returns it to the caller.
        assert(Capacity() > Count());
        T nObj; // new object
        T *nElement = &nObj; // address of new object
        oBuffer += items;    // incrementing pointer by item count    
            oBuffer = (char*) nElement; // attempt to store object address in buffer[items] location
        items++; // increment items count by one
        return (T*) &oBuffer;
    }

    T *  operator [] (unsigned nIndex){         ///======   Returns the n th element of the container [0..Count -1].
        return (T*) (&oBuffer[nIndex]);
    }

};

#endif

Originally I was trying to do the add as follows:

T *  Add(){             ///======   Adds an element to the container, constructs it and returns it to the caller.
        assert(Capacity() > Count());
        T *add =&(oBuffer[items++] = T{});
        return add;
    }

But I would come into problems when T = was a custom class object.

Community
  • 1
  • 1
  • What you're trying to do there won't work. What you're looking for is serialization. – πάντα ῥεῖ Sep 04 '13 at 06:33
  • @g-makulik is it possible that you can give an example of serialization in this case? I haven't done much serialization and any examples would be helpful. – hellfiremarine Sep 04 '13 at 07:12
  • It's a wide field. You may start with the link from Joachim Pileborg's answer. Boost provides a serialization library, [s11n](http://s11n.net/) is another one. Also besides serialization [placement new](http://stackoverflow.com/questions/222557/what-uses-are-there-for-placement-new) might be what you're looking for, depends on your use case. – πάντα ῥεῖ Sep 04 '13 at 07:12

1 Answers1

1

You have undefined behaviors in your Add function, as first you store a pointer to a local variable (with oBuffer = (char*) nElement), then with the same statement you overwrite the original pointer, which you already overwritten in the statement above, and then you return the address of the pointer (i.e. char **) but cast it as a single pointer.

Your indexing function also will not work, as nIndex is the index in the char "array" and will not be the same unless the templated type T is char.

If you want to store objects of a certain type, use std::vector.

If you want serialization for saving to file/sending over network, it won't work either for any type containing pointer, collections, files etc.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621