[pgrouting-dev] Using pfree/palloc in c++ code.

Dave Potts dave.potts at pinan.co.uk
Wed Aug 14 23:28:55 PDT 2013


On 15/08/13 02:21, Stephen Woodbridge wrote:
> On 8/14/2013 6:19 PM, Dave Potts wrote:
>> I am trying to write some code in c++
>>
>> Its suggested that I should pfree/pmalloc to delete and free memory.
>>
>> Problem is that when I use them,  I get an error from the loader
>>
>> select pgr_sql_check_tsp('select * from edge4');
>> ERROR:  could not load library
>> "/usr/lib/postgresql/9.1/lib/librouting_tsp.so":
>> /usr/lib/postgresql/9.1/lib/librouting_tsp.so: undefined symbol:
>> _Z18MemoryContextAllocP17MemoryContextDatam
>> atsp=#
>>
>> It looks like a name mangling issue
>>
>> I tried inserting extern "C" statments around the postgres include files
>> (palloc.h) in my code because I discovered that, postgres source does
>> not do this, results same issue.
>>
>> I noticed that ./src/apsp_warshall/src/apsp_boost_wrapper.cpp, has an
>> instance of pfree commented out, is there a reasons for this?
>>
>> Does anybody known
>>
>> 1.  Is it possible to use pfree/palloc in a potgres cpp file?
>
> I don't recommend doing this because this memory is allocated in 
> various contexts that are not always obvious and if the context goes 
> out of scope the all the memory allocated in that context is no longer 
> valid. Also memory that is palloc does not need to be pfree'd because 
> it gets cleaned when the context is done with.
>
>> 2.  Can I use  new/malloc/delete etc instead of pfree/palloc
>
> Yes this is the way to go, there are no problems with this. One thing 
> I will comment on with C++ is that if you are using std::vector, then 
> do not push back large struct objects, instead create them with new() 
> and push a pointer onto std::vector then later, delete all the objects 
> based on their points on the std::vector. We had to change a lot of 
> code to prevent std::bad_alloc when we tried to push the objects 
> rather than their pointers
>
> -Steve
hi Steve,

The problem is with the 'name managler', to ensure that enclosure, 
access to scope rules etc  is done 'correctly' all symbols that would be 
could be accessed from cpp module have their names mangled, ie a call to 
pfree is rewritten to _Z18MemoryContextAllocP17MemoryContextDatam.  
Inserting the code 'extern C {' should stop this happening.  I tried it 
around all of the included postgres files, again it did'nt work as expected.

My solution is to cheat!  I have a driver function bar.c which calls 
some code in foo.cpp, in bar.c  I added the following routines

void * getMem(size_t request ){
         return palloc(request);
}
void releaseMem(void *mem ){
         pfree (mem);
}
in foo.cpp, I defined them as

extern "C" {

void * getMem(size_t request );
void releaseMem(void *mem );
}

My code links correctly, with no errors.  The problem is really with the 
Postgres header files, they should be desgined to called from cpp 
instead of just c.  Not nice but a minor hack that seems to resolve the 
current issue.

I take the point about std::vector,std::bad_alloc and their friends.  I 
will define my data structures in such a way that they will not be 
automatically allocated or extended for me by the helpful C++ run time 
system.  This should avoid the issue.

Dave.

>
>> regards
>>
>> Dave.
>> _______________________________________________
>> pgrouting-dev mailing list
>> pgrouting-dev at lists.osgeo.org
>> http://lists.osgeo.org/mailman/listinfo/pgrouting-dev
>
> _______________________________________________
> pgrouting-dev mailing list
> pgrouting-dev at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/pgrouting-dev



More information about the pgrouting-dev mailing list