FAQ
hi,

iirc, in C if I store somwhere a pointer to a "stack" value (e.g.:
call a function with an auto variable, return its pointer) i know i'm
going to mess things, since that piece of data will be most probably
overwritten by subsequent calls.

if I do the same in Perl (with a hard ref), do I have any guarantee
that the same behavior (implicit aliasing) does - or does not (every
new scalar is guaranteed to not alias the old non existant value) -
apply?

thank you in advance
gst

Search Discussions

  • Tom Phoenix at Jan 1, 2008 at 5:52 pm

    On Dec 31, 2007 2:43 PM, gst wrote:

    iirc, in C if I store somwhere a pointer to a "stack" value (e.g.:
    call a function with an auto variable, return its pointer) i know i'm
    going to mess things, since that piece of data will be most probably
    overwritten by subsequent calls.

    if I do the same in Perl (with a hard ref), do I have any guarantee
    that the same behavior (implicit aliasing) does - or does not (every
    new scalar is guaranteed to not alias the old non existant value) -
    apply?
    You can't do "the same" in Perl. Problem solved!

    Perl itself handles such things as memory management and the stack.
    Perl programmers rarely need to think about such things. If you try
    writing a test program that does what you're thinking of, you should
    see that Perl allocates new lexical variables as needed (and I
    shouldn't tell you this, but it doesn't really keep them on the
    stack), so your program won't segfault like a C program might.

    Cheers!

    --Tom Phoenix
    Stonehenge Perl Training
  • Yitzle at Jan 1, 2008 at 6:45 pm
    IIRC, the stack pointer is part of the operating system, not the C language.
    When a subroutine is called, the parameters are pushed to the stack,
    and the return value is stored in a specific register.
    When a routine creates a variable, the system's memory allocator finds
    a new piece of unused memory to use.
    If you call a routine (or function) that creates a variable, when the
    routine returns, the memory is marked free, but the OS does not clean
    the memory, so the contents can still be accessed, until the OS reuses
    that memory.
    What are you trying to do? Access that memory? Why? Are you trying to
    return a reference from a subroutine and access what is referenced?
    You can do that. As long as memory is referenced, Perl does not
    release it.

    Hope this helped!
    On Dec 31, 2007 5:43 PM, gst wrote:
    hi,

    iirc, in C if I store somwhere a pointer to a "stack" value (e.g.:
    call a function with an auto variable, return its pointer) i know i'm
    going to mess things, since that piece of data will be most probably
    overwritten by subsequent calls.

    if I do the same in Perl (with a hard ref), do I have any guarantee
    that the same behavior (implicit aliasing) does - or does not (every
    new scalar is guaranteed to not alias the old non existant value) -
    apply?

    thank you in advance
    gst
  • Jenda Krynicky at Jan 3, 2008 at 12:09 am
    From: yitzle <yitzle@users.sourceforge.net>
    IIRC, the stack pointer is part of the operating system, not the C language.
    When a subroutine is called, the parameters are pushed to the stack,
    and the return value is stored in a specific register.
    Well ... depends. If you want to call a function provided by the OS
    you have to do what the OS expects. You have to put the parameters
    that function expects in the expected format at the expected place.
    OTOH, how do you internaly call functions is really up to you and the
    OS doesn't play any part in that.
    When a routine creates a variable, the system's memory allocator finds
    a new piece of unused memory to use.
    Not necessarily true. Most likely the process's internal memory
    allocator finds a new piece of unused memory and only if it can't
    find any asks the OS's memory allocator for some more. And it asks
    for a big block, not just for a piece that you need at the moment.
    If you call a routine (or function) that creates a variable, when the
    routine returns, the memory is marked free, but the OS does not clean
    the memory, so the contents can still be accessed, until the OS reuses
    that memory.
    1) "my" variables have a BLOCK scope, not a subroutine scope.
    The memory is marked free (returned to the process's memory
    allocator) whenever you loose the last reference to it. Which may be
    because a variable ran out of scope (that is the block in which it
    was declared ended) or because you undefed or changed the value of
    the last variable that held a reference to the value stored there.

    Whether that memory is cleared or not is undefined and irrelevant as
    there is no way to access it. (well, unless you are really cheeky,
    did keep a stringified address and use something that allows you to
    peek under the hood. Don't do that!)
    What are you trying to do? Access that memory? Why? Are you trying to
    return a reference from a subroutine and access what is referenced?
    You can do that. As long as memory is referenced, Perl does not
    release it.
    You are right in that one.

    Jenda
    ===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz =====
    When it comes to wine, women and song, wizards are allowed
    to get drunk and croon as much as they like.
    -- Terry Pratchett in Sourcery
  • Chas. Owens at Jan 1, 2008 at 7:12 pm

    On Dec 31, 2007 5:43 PM, gst wrote:
    hi,

    iirc, in C if I store somwhere a pointer to a "stack" value (e.g.:
    call a function with an auto variable, return its pointer) i know i'm
    going to mess things, since that piece of data will be most probably
    overwritten by subsequent calls.

    if I do the same in Perl (with a hard ref), do I have any guarantee
    that the same behavior (implicit aliasing) does - or does not (every
    new scalar is guaranteed to not alias the old non existant value) -
    apply?

    thank you in advance
    gst
    When you say

    my @refs;

    for (1 .. 5) {
    my $value;
    push @refs, \$value;
    }

    You get five distinct memory locations. Each time the my function is
    executed you get a new memory address. This is why things like
    closures work. Saying my in Perl is like* saying

    struct scalar_struct* var = malloc(sizeof(struct scalar_struct));

    with the call to free() being handled for by the garbage collection
    system (when the number of references goes to zero).

    * this is not literal
  • Chas. Owens at Jan 1, 2008 at 7:32 pm
    On Jan 1, 2008 2:12 PM, Chas. Owens wrote:
    snip
    if I do the same in Perl (with a hard ref), do I have any guarantee
    that the same behavior (implicit aliasing) does - or does not (every
    new scalar is guaranteed to not alias the old non existant value) -
    apply?
    snip
    Saying my in Perl is like* saying

    struct scalar_struct* var = malloc(sizeof(struct scalar_struct));

    with the call to free() being handled for by the garbage collection
    system (when the number of references goes to zero).

    * this is not literal
    snip

    Of course, this does not mean you might not run into problems. For
    instance, the DBI module uses only one array (it is only my'ed once
    for efficiency reasons) for each query when you use the fetch method*.
    So you cannot safely say

    my @rows;
    $sth->execute;
    while (my $array_ref = $sth->fetch) {
    push @rows, $array_ref;
    }
    #all of the elements of @rows will be the same because $array_ref is
    #always a reference to the same my'ed variable

    You can deal with this by using the anonymous arrayref generator:

    my @rows;
    $sth->execute;
    while (my $array_ref = $sth->fetch) {
    push @rows, [@$array_ref];
    }
    #each element of @rows will be different
    #because a new annonymous array was
    #created by each call to [] and the contents
    #of the array referenced by $array_ref were
    #copied to it.

    You can think of [] (when not being used as the offset operator) as
    looking like this

    sub anonymous_arrayref_generator {
    my @list = @_;
    return \@list;
    }

    In general, you can expect anything returned to you is a new memory
    address unless specifically documented as otherwise.

    * from http://search.cpan.org/dist/DBI/DBI.pm#fetchrow_arrayref
    "fetchrow_arrayref"
    $ary_ref = $sth->fetchrow_arrayref;
    $ary_ref = $sth->fetch; # alias

    Fetches the next row of data and returns a reference to an array
    holding the field values. Null fields are returned as "undef" val‐
    ues in the array. This is the fastest way to fetch data, particu‐
    larly if used with "$sth->bind_columns".

    If there are no more rows or if an error occurs, then
    "fetchrow_arrayref" returns an "undef". You should check
    "$sth->err" afterwards (or use the "RaiseError" attribute) to dis‐
    cover if the "undef" returned was due to an error.

    Note that the same array reference is returned for each fetch, so
    don't store the reference and then use it after a later fetch.
    Also, the elements of the array are also reused for each row, so
    take care if you want to take a reference to an element. See also
    "bind_columns".
  • Chas. Owens at Jan 1, 2008 at 7:36 pm
    On Jan 1, 2008 2:32 PM, Chas. Owens wrote:
    snip
    You can deal with this by using the anonymous arrayref generator:
    snip

    Oh, the proper term is "anonymous array composer" (at least according
    to the 3rd Camel). I knew "anonymous arrayref generator" sounded
    wrong.
  • Groups spamtrap at Jan 1, 2008 at 8:20 pm
    thanks everyone a lot, you cleared up any doubt, *very* insightful

    have a wonderful happy new year!

    On Jan 1, 2008 8:36 PM, Chas. Owens wrote:

    On Jan 1, 2008 2:32 PM, Chas. Owens wrote:
    snip
    You can deal with this by using the anonymous arrayref generator:
    snip

    Oh, the proper term is "anonymous array composer" (at least according
    to the 3rd Camel). I knew "anonymous arrayref generator" sounded
    wrong.
  • Peter Scott at Jan 1, 2008 at 7:35 pm

    On Mon, 31 Dec 2007 14:43:44 -0800, gst wrote:
    iirc, in C if I store somwhere a pointer to a "stack" value (e.g.:
    call a function with an auto variable, return its pointer) i know i'm
    going to mess things, since that piece of data will be most probably
    overwritten by subsequent calls.

    if I do the same in Perl (with a hard ref), do I have any guarantee
    that the same behavior (implicit aliasing) does - or does not (every
    new scalar is guaranteed to not alias the old non existant value) -
    apply?
    I'm not entirely clear what it is you're either trying to do or trying to
    avoid. Usually one takes a copy of a subroutine argument to work on it:

    sub frobble {
    my $arg = shift; # same as my $arg = $_[0];
    # Work on $arg
    }

    The @_ array contains aliases for the arguments, so that you can change
    them (this is uncommon and almost always a bad design):

    sub fnord { $_[0]++ }
    fnord( my $x = 42 ); # $x == 43
    fnord( 42 ); # Error: attempt to modify r/o value

    Perl does reference-based garbage collection, so as long as a reference
    (this is an internal reference, not a perlref sort of reference) to
    something exists, that thing will not go away. So a subroutine can
    create a new variable, return a reference to it, and as long as the
    storage that receives that reference is in use, the storage the reference
    refers to will be retained, even if it becomes anonymous.

    If you return a reference to some element of @_, the aliasing means it is
    as if you had enreferenced whatever was passed in that argument position.

    If that doesn't answer your question, I suggest you read perlref and post
    some sample code you are concerned about. If you've written something
    that involves just package and/or lexical variables, subroutine calls,
    enreferencing and dereferencing operators, and use of the @_ array and are
    wondering whether the resulting behavior can be counted on being
    consistent on every perl (5) and every platform, the answer is yes.
  • Jenda Krynicky at Jan 1, 2008 at 8:55 pm
    From: gst <groups.spamtrap@gmail.com>
    iirc, in C if I store somwhere a pointer to a "stack" value (e.g.:
    call a function with an auto variable, return its pointer) i know i'm
    going to mess things, since that piece of data will be most probably
    overwritten by subsequent calls.

    if I do the same in Perl (with a hard ref), do I have any guarantee
    that the same behavior (implicit aliasing) does - or does not (every
    new scalar is guaranteed to not alias the old non existant value) -
    apply?
    There is no real stack in Perl as far as variables are concerned and
    if there are any references left to a value, it will stay put and
    will never be overwritten by new variables.

    You can even do things like:

    while (<>) {
    my @items = split ',', $_;
    my %row = (name => $items[0], email => $items[1], age =>
    $items[2]);

    push @people, \%row;
    }

    and it will work well ... each iteration will get a new hash and the
    %people array will contain as many different hashes as there was
    lines in the input.

    Jenda
    ===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz =====
    When it comes to wine, women and song, wizards are allowed
    to get drunk and croon as much as they like.
    -- Terry Pratchett in Sourcery
  • Paul Johnson at Jan 1, 2008 at 10:59 pm

    On Mon, Dec 31, 2007 at 02:43:44PM -0800, gst wrote:

    hi,

    iirc, in C if I store somwhere a pointer to a "stack" value (e.g.:
    call a function with an auto variable, return its pointer) i know i'm
    going to mess things, since that piece of data will be most probably
    overwritten by subsequent calls.

    if I do the same in Perl (with a hard ref), do I have any guarantee
    that the same behavior (implicit aliasing) does - or does not (every
    new scalar is guaranteed to not alias the old non existant value) -
    apply?
    In addition to the answers you have received, you will be pleased to
    hear that in contrast to C, Perl doesn't do variable suicide in the
    manner you have described. Variables are reference counted, and will
    not be destroyed until the last reference to them is deleted.

    --
    Paul Johnson - paul@pjcj.net
    http://www.pjcj.net

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedJan 1, '08 at 1:09a
activeJan 3, '08 at 12:09a
posts11
users7
websiteperl.org

People

Translate

site design / logo © 2021 Grokbase