http://www.perlmonks.org?node_id=516909

needperlhelp has asked for the wisdom of the Perl Monks concerning the following question:

I have an global associative array %g_User; with keys as userids
for each user i want to dynamically create an array and attach its refrence to the value of the associative array as shown below

$g_User{'user1'} = \@l_UserDetails;

but i face the following problem;
> if dont declare the array @l_UserDetails, the variable is global and all users refer to the same array
> if i delare array with my / local , they will get destroyed when the control comes out of the function in which the addition happens

do we have something simillar to new / malloc in perl
or
is there a simpler way to handle this situation in perl
please help

Replies are listed 'Best First'.
Re: Dynamic Memory allocation
by salva (Canon) on Dec 15, 2005 at 10:22 UTC
    if i declare array with my, they will get destroyed when the control comes out of the function in which the addition

    No, it will not. Perl automatic memory handling takes care of these things.

    You can also use the [] operator as ...

    $g_User{user1} = [@l_UserDetails];
    to create a copy of the array and get a reference to it.
Re: Dynamic Memory allocation
by tirwhan (Abbot) on Dec 15, 2005 at 10:24 UTC
    if i delare array with my / local , they will get destroyed when the control comes out of the function in which the addition happens

    This is wrong, Perl5 counts the references to a variable/data structure and only destroys the container if no more references are held. Since you are keeping a reference to your array in the the hash, the array will only be destroyed when your hash goes away (i.e. goes out of scope with no more references held to it) and is destroyed itself.


    Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
Re: Dynamic Memory allocation
by Corion (Patriarch) on Dec 15, 2005 at 10:25 UTC

    How did you check that the array gets destroyed when the control leaves your function?

    use strict; my %g_User; sub setup_user_details { my ($username) = @_; my @l_UserDetails = ("John","Doe"); $g_user{$username} = \@l_UserDetails; }; setup_user_details('user1');

    Your naming convention is a bit unwieldly, but I attribute that to your company coding guidelines. In Perl it's conventional to use lower_caps_names instead of CamelCase, and prefixing of variables with their scope is uncommon because the strict pragma enforces proper scoping.

Re: Dynamic Memory allocation
by Tomte (Priest) on Dec 15, 2005 at 10:22 UTC

    Use an anonymous array-ref "in situ":

    $g_User{'user1'} = []; $g_User{'user1'}->[0] = 'Hans'; $g_User{'user1'}->[1] = 'Wurst'; print join ' ', @{$g_User{'user1'}}; __END__ Hans Wurst

    regards,
    tomte


    An intellectual is someone whose mind watches itself.
    -- Albert Camus

Re: Dynamic Memory allocation
by Moron (Curate) on Dec 15, 2005 at 14:10 UTC
    If the my @l_UserDetails is declared at main scope, the array inside the hash is indeed the same array.

    To give it a life of its own instead, a copy of the array first has to be declared with dynamic scope:

    my %g_User; my @l_UserDetails = ('hallo','goodbye'); InsertArray( \@l_UserDetails, \%g_User, 'user1' ); sub InsertArray { my $aref = shift; my $href = shift; my $elt = shift; my @dynamic = @$aref; $href -> { $elt } = \@dynamic; }

    -M

    Free your mind

Re: Dynamic Memory allocation
by blazar (Canon) on Dec 15, 2005 at 14:21 UTC
    $g_User{'user1'} = \@l_UserDetails;

    To answer your question:

    $g_User{'user1'} = [@l_UserDetails];

    But then chances are you may avoid @l_UserDetails altogether, if the code that fills it is simple enough, that is.