Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Help with a bad bug: why is my original array being altered??

Reply
Thread Tools

Help with a bad bug: why is my original array being altered??

 
 
Alf McLaughlin
Guest
Posts: n/a
 
      03-17-2006
Hello all-
Please look at the code at the code listed below. It produces the
result also listed below. My question is, I have absolutely no idea
why the values in my original array are changing when I perform
operations on the second array. I am totally stumped... I do not
understand why the @match array seems to share the same memory address
as @array. Any help is much appreciated!

Thanks, Alf

THE RESULT:

In match array:
===============
70 c
75 d
77 e
88 f
In original array:
==================
4 a
6 b
700000 c
750000 d
770000 e
880000 f
99 g
100 h
105 i
200 j
300 k

THE CODE:

#!/usr/bin/perl

MAIN: {
my $ra_array = get_array();
my $low_range = 68;
my $high_range = 90;
my @match = grep {my $i = $_; $i->[0] >= $low_range and $i->[0] <=
$high_range} @$ra_array;
print "In match array:\n";
print "===============\n";
foreach my $i (@match) {
print "$i->[0]\t$i->[1]\n";
$i->[0] *= 10000;
}
print "In original array:\n";
print "==================\n";
foreach my $i (@$ra_array) {
print "$i->[0]\t$i->[1]\n";
}
}

sub get_array {
my @array; #= (4, 6, 70, 75, 77, 88, 99, 100, 105, 200, 300);
$array[0] = [(4, 'a')];
$array[1] = [(6, 'b')];
$array[2] = [(70, 'c')];
$array[3] = [(75, 'd')];
$array[4] = [(77, 'e')];
$array[5] = [(88, 'f')];
$array[6] = [(99, 'g')];
$array[7] = [(100, 'h')];
$array[8] = [(105, 'i')];
$array[9] = [(200, 'j')];
$array[10] =[(300, 'k')];
return \@array;
}

 
Reply With Quote
 
 
 
 
takarov2003@yahoo.com
Guest
Posts: n/a
 
      03-17-2006
Alf McLaughlin wrote:
> Hello all-
> Please look at the code at the code listed below. It produces the
> result also listed below. My question is, I have absolutely no idea
> why the values in my original array are changing when I perform
> operations on the second array. I am totally stumped... I do not
> understand why the @match array seems to share the same memory address
> as @array. Any help is much appreciated!
>
> Thanks, Alf
>
> THE RESULT:
>
> In match array:
> ===============
> 70 c
> 75 d
> 77 e
> 88 f
> In original array:
> ==================
> 4 a
> 6 b
> 700000 c
> 750000 d
> 770000 e
> 880000 f
> 99 g
> 100 h
> 105 i
> 200 j
> 300 k
>
> THE CODE:
>
> #!/usr/bin/perl
>
> MAIN: {
> my $ra_array = get_array();
> my $low_range = 68;
> my $high_range = 90;
> my @match = grep {my $i = $_; $i->[0] >= $low_range and $i->[0] <=
> $high_range} @$ra_array;
> print "In match array:\n";
> print "===============\n";
> foreach my $i (@match) {
> print "$i->[0]\t$i->[1]\n";
> $i->[0] *= 10000;


aren't you multiplying your array content here by 10,000?

> }
> print "In original array:\n";
> print "==================\n";
> foreach my $i (@$ra_array) {
> print "$i->[0]\t$i->[1]\n";
> }
> }
>


 
Reply With Quote
 
 
 
 
Uri Guttman
Guest
Posts: n/a
 
      03-17-2006
>>>>> "AM" == Alf McLaughlin <(E-Mail Removed)> writes:

AM> Please look at the code at the code listed below. It produces the
AM> result also listed below. My question is, I have absolutely no idea
AM> why the values in my original array are changing when I perform
AM> operations on the second array. I am totally stumped... I do not
AM> understand why the @match array seems to share the same memory address
AM> as @array. Any help is much appreciated!

AM> MAIN: {
AM> my $ra_array = get_array();
AM> my @match = grep {my $i = $_; $i->[0] >= $low_range and $i->[0] <=
AM> $high_range} @$ra_array;

that copies the array refs in the input array. they are the same anon
arrays as in the input. you did a shallow copy (filtered by grep). you
need to loop over each of those and make a deeper copy. if you know that
you will have just that data structure a map will do a proper deep copy
(untested):

my @copies = map [ @{$_} ], @match ;

now if you modify anything in @copies it won't touch the original
anon arrays in @match. you can combine that map with the grep if you
want.

AM> print "In match array:\n";
AM> print "===============\n";
AM> foreach my $i (@match) {
AM> print "$i->[0]\t$i->[1]\n";
AM> $i->[0] *= 10000;
AM> }

use some white space and better formatting.
AM> sub get_array {

if the array is fixed why regenerate it each time in this code?

AM> my @array; #= (4, 6, 70, 75, 77, 88, 99, 100, 105, 200, 300);
AM> $array[0] = [(4, 'a')];
AM> $array[1] = [(6, 'b')];
AM> $array[2] = [(70, 'c')];

ewww, i hate seeing repetitive code like that. just assign the anon
arrays in a single list:

my @array = (
[(4, 'a')],
[(6, 'b')],
) ;

uri

--
Uri Guttman ------ http://www.velocityreviews.com/forums/(E-Mail Removed) -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
 
Reply With Quote
 
Brian McCauley
Guest
Posts: n/a
 
      03-17-2006

Alf McLaughlin wrote:
> Please look at the code at the code listed below. It produces the
> result also listed below. My question is, I have absolutely no idea
> why the values in my original array are changing when I perform
> operations on the second array. I am totally stumped... I do not
> understand why the @match array seems to share the same memory address
> as @array.


It does not. The elements of @match are independant of those of @array.
But the elements of @array are refereneces to things (anonymous arrays
as it happens) and the elements of @match are references to the very
same things.

So in the code below $match[0] is not the same thing as $array[2] it
just happens to have the same value. But consequently $match[0][0] is
the same thing as $array[2][0].

> MAIN: {
> my $ra_array = get_array();
> my $low_range = 68;
> my $high_range = 90;
> my @match = grep {my $i = $_; $i->[0] >= $low_range and $i->[0] <=
> $high_range} @$ra_array;
> print "In match array:\n";
> print "===============\n";
> foreach my $i (@match) {
> print "$i->[0]\t$i->[1]\n";
> $i->[0] *= 10000;
> }
> print "In original array:\n";
> print "==================\n";
> foreach my $i (@$ra_array) {
> print "$i->[0]\t$i->[1]\n";
> }
> }
>
> sub get_array {
> my @array; #= (4, 6, 70, 75, 77, 88, 99, 100, 105, 200, 300);
> $array[0] = [(4, 'a')];
> $array[1] = [(6, 'b')];
> $array[2] = [(70, 'c')];
> $array[3] = [(75, 'd')];
> $array[4] = [(77, 'e')];
> $array[5] = [(88, 'f')];
> $array[6] = [(99, 'g')];
> $array[7] = [(100, 'h')];
> $array[8] = [(105, 'i')];
> $array[9] = [(200, 'j')];
> $array[10] =[(300, 'k')];
> return \@array;
> }


 
Reply With Quote
 
Alf McLaughlin
Guest
Posts: n/a
 
      03-17-2006
>my @copies = map [ @{$_} ], @match ;

Thanks, that's just what I needed; your explanation makes sense.

>if the array is fixed why regenerate it each time in this code?


Just for an example (the real array in my actual program comes from
something else).

>ewww, i hate seeing repetitive code like that. just assign the anon
>arrays in a single list:


Sure, that works too. Again, I usually automate array generation

 
Reply With Quote
 
xhoster@gmail.com
Guest
Posts: n/a
 
      03-17-2006
"Alf McLaughlin" <(E-Mail Removed)> wrote:
> Hello all-
> Please look at the code at the code listed below. It produces the
> result also listed below. My question is, I have absolutely no idea
> why the values in my original array are changing when I perform
> operations on the second array.


Your original arrays contains references to other two-element arrays.
The values (i.e. references) in your original array are not changing. It
is the values in the small arrays being referenced by the values in the
original array that are changing.


> I am totally stumped... I do not
> understand why the @match array seems to share the same memory address
> as @array. Any help is much appreciated!


That is how references work. Either make a deep(er) copy of the small
arrays, or simply don't change them.

@match = map [@$_], grep {...} @$ra_array;

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
 
Reply With Quote
 
Glenn Jackman
Guest
Posts: n/a
 
      03-17-2006
At 2006-03-17 01:01PM, Alf McLaughlin <(E-Mail Removed)> wrote:
> >my @copies = map [ @{$_} ], @match ;

>
> Thanks, that's just what I needed; your explanation makes sense.


See also http://www.stonehenge.com/merlyn/UnixReview/col30.html

--
Glenn Jackman
Ulterior Designer
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Bad media, bad files or bad Nero? John Computer Information 23 01-08-2008 09:17 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
ActiveX apologetic Larry Seltzer... "Sun paid for malicious ActiveX code, and Firefox is bad, bad bad baad. please use ActiveX, it's secure and nice!" (ok, the last part is irony on my part) fernando.cassia@gmail.com Java 0 04-16-2005 10:05 PM
24 Season 3 Bad Bad Bad (Spoiler) nospam@nospam.com DVD Video 12 02-23-2005 03:28 AM
24 Season 3 Bad Bad Bad (Spoiler) nospam@nospam.com DVD Video 0 02-19-2005 01:10 AM



Advertisments