Home > Archive > Prolog > March 2006 > (Interfacing Prolog) pointer issue (SWI)
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
(Interfacing Prolog) pointer issue (SWI)
|
|
| Mauro Di Nuzzo 2006-03-17, 6:58 pm |
| Hi All.
I am currently using SWI Prolog 5.6.x.
Note that I am not an expert C programmer.
I have the following C code (compiled into a dll):
-----------
#include <SWI-Prolog.h>
#include <stdlib.h>
#include <ctype.h>
foreign_t alloci(term_t address) {
int result = PL_unify_pointer(address, (void *)malloc(sizeof(int)));
return result;
}
-----------
This code is evidently completely unuseful, since it doesnt work as I
dreamt. In particular, after load_foreign_library/1 call, I try the
following:
?- alloci(P1), alloci(P2).
P1 = 1069858230
P2 = 1069858230
that is, space allocated by the first call is deallocated on exiting and
reallocated by the second call. Isnt it? In other word I am unable to
allocate memory that remains, lets say, allocated even in Prolog toplevel
(or whatever).
Does anyway to do this (if someone have understood my terrible explanation)
exist?
Thanks a lot.
/\/\
| |
| Jan Wielemaker 2006-03-18, 6:57 pm |
| On 2006-03-17, Mauro Di Nuzzo <picorna@inwind.it> wrote:
> Hi All.
> I am currently using SWI Prolog 5.6.x.
> Note that I am not an expert C programmer.
> I have the following C code (compiled into a dll):
> -----------
> #include <SWI-Prolog.h>
> #include <stdlib.h>
> #include <ctype.h>
> foreign_t alloci(term_t address) {
> int result = PL_unify_pointer(address, (void *)malloc(sizeof(int)));
> return result;
> }
> -----------
> This code is evidently completely unuseful, since it doesnt work as I
> dreamt. In particular, after load_foreign_library/1 call, I try the
> following:
>
> ?- alloci(P1), alloci(P2).
> P1 = 1069858230
> P2 = 1069858230
This is, to say the least, very odd. No, Prolog doesn't try to interfere
with your calls to malloc(). It doesn't free that memory for you. It has
no (portable) means to know you did a malloc().
Try
#include <SWI-Stream.h>
#include <SWI-Prolog.h>
#include <stdlib.h>
static foreign_t
alloci(term_t address)
{ int *ptr = malloc(sizeof(int));
if ( PL_unify_pointer(address, ptr) )
{ void *p2;
if ( !PL_get_pointer(address, &p2) )
Sdprintf("Can't get pointer!?\n");
if ( p2 != (void*)ptr )
Sdprintf("Inconsistent result: ptr=%p, p2=%p\n", ptr, p2);
return TRUE;
}
return FALSE;
}
install_t
install()
{ PL_register_foreign("alloci", 1, alloci, 0);
}
Here (Linux) I get:
% plld -o t -shared t.c
% pl
1 ?- load_foreign_library(t).
Yes
2 ?- alloci(P1), alloci(P2).
P1 = 266282
P2 = 281328
If you get one of the messages, file a bug report at the SWI-Prolog
bugzilla.
--- Jan
P.s. Reporting such problems, always send a *complete* program others
can compile and try. It makes it a lot easier to reproduce and
help.
| |
| Mauro Di Nuzzo 2006-03-19, 6:57 pm |
| Thank You Jan. Very kind as always.
Your code works well.
But I want to submit you a "strange" behaviour of the following code that I
am unable to explain.
In particular, I implement alloci/1 and alloci/2 predicates. The first just
allocate memory (and unify pointer). The second do the job of the first, but
set also the value of the pointed address to an integer (the 2nd arg of
alloci/2). Code follows:
-------
#include <ctype.h>
#include <SWI-Prolog.h>
#include <stdlib.h>
static foreign_t
pl_alloci1(term_t address)
{
int * ptr = malloc(sizeof(int));
return (PL_unify_pointer(address, ptr));
}
static foreign_t
pl_alloci2(term_t address, term_t integer)
{
int * ptr = malloc(sizeof(int));
int i;
PL_get_integer(integer, &i);
ptr = &i;
return (PL_unify_pointer(address, ptr));
}
install_t
install()
{
PL_register_foreign("alloci1", 1, pl_alloci1, 0);
PL_register_foreign("alloci2", 2, pl_alloci2, 0);
}
-------
After load_foreign_library/1, I call:
?- alloci1(P1), alloci1(P2). % works as expected
P1 = 1069858200
P2 = 1069858290
yes
?- alloci2(P1,1), alloci2(P2,2). % now what happens?
P1 = 1069858230
P2 = 1069858230
yes
How is it possible?
Very thanks again.
/\/\
| |
| Jan Wielemaker 2006-03-20, 3:57 am |
| On 2006-03-19, Mauro Di Nuzzo <picorna@inwind.it> wrote:
> Thank You Jan. Very kind as always.
> Your code works well.
> But I want to submit you a "strange" behaviour of the following code that I
> am unable to explain.
> In particular, I implement alloci/1 and alloci/2 predicates. The first just
> allocate memory (and unify pointer). The second do the job of the first, but
> set also the value of the pointed address to an integer (the 2nd arg of
> alloci/2). Code follows:
> -------
> #include <ctype.h>
> #include <SWI-Prolog.h>
> #include <stdlib.h>
>
> static foreign_t
> pl_alloci1(term_t address)
> {
> int * ptr = malloc(sizeof(int));
> return (PL_unify_pointer(address, ptr));
> }
>
> static foreign_t
> pl_alloci2(term_t address, term_t integer)
> {
> int * ptr = malloc(sizeof(int));
> int i;
> PL_get_integer(integer, &i);
> ptr = &i;
This is wrong. You're setting ptr to the address of i, while you
want to put i at the address of ptr:
*ptr = i;
> return (PL_unify_pointer(address, ptr));
> }
Cheers --- Jan
| |
| Mauro Di Nuzzo 2006-03-20, 6:58 pm |
| My mistake. Sorry and thanks again.
/\/\
"Jan Wielemaker" <jan@nospam.ct.xs4all.nl> ha scritto nel messaggio
news:slrne1sqru.1a4.jan@ct.lan...
> On 2006-03-19, Mauro Di Nuzzo <picorna@inwind.it> wrote:
that I[color=darkred]
just[color=darkred]
but[color=darkred]
>
> This is wrong. You're setting ptr to the address of i, while you
> want to put i at the address of ptr:
>
> *ptr = i;
>
>
> Cheers --- Jan
|
|
|
|
|