gcc<->gpc: reallocating and disposing buffers
George Shapovalov
gerr at its.caltech.edu
Sat Aug 11 05:39:56 CEST 2001
Hello.
I am sorry for somewhat lengthy email, I tried to get most of the details
here. I could not find detailed discussion of this topic in documentation,
so this is a short investigation.
First some description: I need to implement access to some data stored in
special binary format for reading which large chunks of C code exist. On the
other hand it would be easier/cleaner to do data processing in pascal (It is
really nice to use schemata for some purposes). So I thought to create some c
functionds which would access data and pass it to pascal program.
It would be nice to have c functions allocate and fill buffers and then have
pascal code dispose them after processing. So I tried to test what happens.
Below is the model code which is supposed to represent such situation. In
fact it tests passage of buffers in both ways:
I allocate small array on pascal side, pass it to c, then reallocate it there
(slightly larger block) - actually I use free and then malloc, but realloc
gave the same result. Then upon return to pascal I dispose the buffer.
To tell the truth I did not expect things to work at all, but it appears
that they do work - one way only. Unfortunately the opposite way to what I
need.
So here goes the code:
(I have gpc 20010623, based on 2.95.3 20010315 (release), gcc 2.95.3, glibc
2.2.2, kernel 2.4.4)
----------
Pascal program
----------
program testFuncInvocation;
type Tst=array[0..9]of char;Pst=^Tst;
var x:Pst;
{$L c.c}
function cfunc(var x:pointer):integer;asmname 'cFunc';
{$L cmem.c}
procedure cFree(p:pointer);C;
begin
writeln('pascal program started');
x:=new(Pst);x^:='0123456789';writeln('x=',x^,', @x=',cardinal(x));
writeln('calling c function...');
cfunc(x);
writeln('back in pascal; new @x=',cardinal(x),', x=',x^);
cFree(x);
end.
-------------
c file: c.c
------------
#include <stdio.h>
#include <stdlib.h>
int cFunc(char** x){
printf("\ncFunc called; x=%s\n",*x);
free(*x);
*x=(char*)malloc(15);
*x="0123456789abcde";
printf("realloced x, new @x=%d, x=%s\n",(int)*x,*x);
fflush(stdout);
}
------------
output of this program:
------------
pascal program started
x=0123456789, @x=134716664
calling c function...
cFunc called; x=0123456789
realloced x, new @x=134659990, x=0123456789abcde
back in pascal; new @x=134659990, x=0123456789
Segmentation fault
---------------------
end of code section
---------------------
So, as can be seen, c has no problem disposing the buffer allocated on pascal
side. Pascal gets back correct address, but then fails to deallocate passed
buffer.
I originally tried dispose(x) in pascal code to deallocate x, with the same
result. So then I thought that might be dispose is not just calling glibc's
free() but is relying on internal tracking of variables. But calling free
directly does not help here.
So what would be the correct way to pass disposable buffers from c to pas,
preferrably without having to specify the size (I mean here the way dispose
and free() work. I understand that I will need to keep track of how many data
I got there)? Well if this will be the only catch I don't mind at all, it's
just easier to make a mistake this way.
George
More information about the Gpc
mailing list