I'd like to start out by thanking everyone for their help.  While I did not
use a solution from the list, some of the advice did help me to better
search for a solution online.  For the benefit of those who encounter this
problem in the future, I will share my solution below:

In a Perl program, do something like this:

sub test_image {
    my ($size) = @_;

    # allocate a block of memory and point to it
    $image = create_image($size);

    # manipulate the image
    clear_image($image,$size);

    # free the memory
    destroy_image($image);

    undef($image);
 }

---------------------------------------------
ORIGINAL C CODE:
---------------------------------------------

char * create_image(int size) {
    char * image;
    New(0,image,size,char);
    return image;
 }

void clear_image(char * image,int size) {
    memset(image,CLEAR,size);
 }

void destroy_image(char * image) {
    Safefree(image);
 }

---------------------------------------------

This results in a segmentation fault.  Using New() and Safefree() in the
same subroutine DOES free the memory properly, though.  I should note this
works fine if you do not free the memory in the script (never call
destroy_image -- it will clean up when the script ends).

The following solution seems to work wonderfully, and required only minor
changes to my code:

---------------------------------------------
NEW C CODE:
---------------------------------------------

SV * create_image(int size) {
    char * image;
    New(0,image,size,char);
    return sv_setref_pv(newSViv(0),"image", (void *)image);
 }

void clear_image(SV * p,int size) {
    char * image = (char *) SvIV(SvRV(p));
    memset(image,CLEAR,size);
 }

void destroy_image(SV * p) {
    char * image = (char *) SvIV(SvRV(p));
    Safefree(image);
 }

---------------------------------------------

Basically, you cast the char * as an SV * when you create it and return it
to Perl, and cast it as a char * when you pass it into a subroutine.
Basically, I had to add one line of code to each subroutine (for each
pointer passed), and I could leave the rest of the code as it was.

I hope someone else finds this useful.

--
Dave

Reply via email to