To be honest there are more clever ways you can do this. For example, you can overload operator new and delete to just call TSmalloc, you can create custom allocators for stl containers, if you overload operator new then you can just do. 

TransformationData *foo = new TransformationData(); // your overloaded operator new calls TSmalloc.
delete foo; // no problems here, you just call TSfree in operator delete

Here is an example:

class Myclass
{
public:
        void* operator new(size_t size) {
            void *tmp = TSmalloc(size);
            if(!tmp)
             throw "allocation failed using TSmalloc";
            return tmp;
        }
        void operator delete(void* mem) {
           TSfree(mem);
        }
};

Now you can just do new Myclass() and it will allocate using TSmalloc and calls to delete will free using TSfree and you'll get everything you normally get with C++. And you can then define a custom allocators to handle allocations in all of the standard library containers using TSmalloc and TSfree... then life is easy.

Also, in C++ you dont need to do typedef struct as struct by itself will do.


On Thu, Jan 24, 2013 at 11:33 PM, Owens, Steve <Steve.Owens@disney.com> wrote:
I think that the approach put forth by Brian and amplified by James is an elegant one, provided you are using a GCC compiler of sufficient recency to support the notion of a placement new.

For me I discovered that I couldn't get the compiler to accept the one liner:

     pData = new ((TransformationData *) TSmalloc(sizeof(TransformationData))) TransformationData();

and ended up having to use:

     TransformationData* pData = (TransformationData*) Tsmalloc(sizeof(TransformationData));
     pData = new (pData) TransformationData();

Also I had to change:
typedef struct {
       int state;
       TSVIO output_vio;
       TSIOBuffer output_buffer;
       TSIOBufferReader output_reader;
       std::string foo;
   } TransformationData;

To 
typedef struct TransformationData {
       int state;
       TSVIO output_vio;
       TSIOBuffer output_buffer;
       TSIOBufferReader output_reader;
        std::string foo;
        TransformationData() {}
     } TransformationData;

In retrospect I could have probably gotten by with the one liner after making the change to the typedef.  If time permits I will test that out tomorrow.

From: Manas Agarwal <manasagarwal81@gmail.com>
Reply-To: "users@trafficserver.apache.org" <users@trafficserver.apache.org>
Date: Thu, 24 Jan 2013 22:21:51 -0800

To: "users@trafficserver.apache.org" <users@trafficserver.apache.org>
Subject: Re: Question on TSMalloc

I too faced similar issue.
I replaced string with string*.  I think the problem is TSMalloc doesn't create and initialize the object as it is based on malloc.


On Fri, Jan 25, 2013 at 10:49 AM, James Peach <jpeach@apache.org> wrote:
On 24/01/2013, at 3:14 PM, Brian Geffon <briang@apache.org> wrote:

> Try just using a placement new.
>
> pData = new ((TransformationData *) TSmalloc(sizeof(TransformationData))) TransformationData();

and don't forget to call the destructor before calling TSfree:
        pData->~TransformationData();
        TSfree(pData);

>
> Brian
>
> On Thu, Jan 24, 2013 at 2:32 PM, Owens, Steve <Steve.Owens@disney.com> wrote:
>
> I ran into a bit of an issue today related to TSMalloc
>
> Suppose I have a plugin which defines a plugin data structure such as:
>
> typedef struct {
>         int state;
>         TSVIO output_vio;
>         TSIOBuffer output_buffer;
>         TSIOBufferReader output_reader;
>         std::string foo;
>     } TransformationData;
>
>
> And I have some plugin code which does this:
>
> void allocTransformationData(){
>       TransformationData *pData;
>
>       pData = (TransformationData *) TSmalloc(sizeof(TransformationData));
>       pData->state = STATE_START;
>       pData->output_buffer = NULL;
>       pData->output_vio = NULL;
>       pData->output_reader = NULL;
>
>       pData->foo.assign("bar");
>
>       return pData;
> }
>
> The line  pData->foo.assign("bar");
>
>
> Will result in a segmentation fault.
>
> Is there a best practice idiom for using std::string items in custom continuation data?  For example should I be using
>
> typedef struct {
>         int state;
>         TSVIO output_vio;
>         TSIOBuffer output_buffer;
>         TSIOBufferReader output_reader;
>         std::string *foo;
>     } TransformationData;
>
> And
>
>
> Void allocTransformationData(){
>       TransformationData *pData;
>
>       pData = (TransformationData *) TSmalloc(sizeof(TransformationData));
>       pData->state = STATE_START;
>       pData->output_buffer = NULL;
>       pData->output_vio = NULL;
>       pData->output_reader = NULL;
>
>
>       pData->foo = new std::string;
>         pData->foo.assign("bar");
>
>       return pData;
> }
>
> Or should I use:
>
> Void allocTransformationData(){
>       TransformationData *pData;
>
>       pData = (TransformationData *) TSmalloc(sizeof(TransformationData));
>       pData->state = STATE_START;
>       pData->output_buffer = NULL;
>       pData->output_vio = NULL;
>       pData->output_reader = NULL;
>
>
>       pData->foo = (std::string*) Tsmalloc(sizeof(std::string));
>         pData->foo.assign("bar");
>
>       return pData;
> }
>
>
>
>
>
>