2014-12-13 6 views
4

서브 루틴의 변수가 메모리를 해제하는시기와 방법에 대한 질문이 있습니다. 스크립트는 예이다 :Perl 서브 루틴의 변수가 메모리를 해제하지 않습니다.

#!perl/bin/per 
use strict; 
sub A{ 
    my $x= shift; 
    return ([$x]); 
} 
for my $i (1..10){ 
    my $ref= &A($i);## the input changes in each round 
    my $ref2= &A(9);## the input is fixed in each round 
    print "$ref\t"; 
    print "$ref2\n"; 
} 

하고 화면에 출력 하였다 :

ARRAY(0x996e98) ARRAY(0x9b50c8) 
ARRAY(0x996e98) ARRAY(0x9b50c8) 
ARRAY(0x996e98) ARRAY(0x9b50c8) 
ARRAY(0x996e98) ARRAY(0x9b50c8) 
ARRAY(0x996e98) ARRAY(0x9b50c8) 
ARRAY(0x996e98) ARRAY(0x9b50c8) 
ARRAY(0x996e98) ARRAY(0x9b50c8) 
ARRAY(0x996e98) ARRAY(0x9b50c8) 
ARRAY(0x996e98) ARRAY(0x9b50c8) 
ARRAY(0x996e98) ARRAY(0x9b50c8) 

내가 참조가 서브 루틴 A는 한번 이상 호출 될 때 변경 될 것을 기대하지만, 출력 입력이 언제 변경되었는지에 관계없이 참조가 수정되었습니다. 그 현상은 전체 스크립트가 끝날 때까지 서브 루틴에서 변수가 차지하는 메모리를 공개 할 수 없다고 추측 할 수 있습니까? 그렇지 않으면 내 결과가 비정상입니까?

답변

8
  1. A($i)에 대한 호출은 perl이 편리하다고 생각하는 모든 위치에서 새로운 arrayref를 할당합니다.
  2. 해당 배열 참조는 루프 본문으로 반환되고 해당 루프 본문에 어휘 적으로 범위가 지정된 변수에 저장됩니다.
  3. 루프의 맨 아래에서 변수는 범위를 벗어나며 그 밖의 요소는 해당 arrayref를 참조하지 않으므로 arrayref는 할당이 해제됩니다.
  4. 따라서 이전 arrayref 개최하는 메모리 위치를 다시 편리하게 사용할 수 있으며, 다음 필요할 때 다시 사용 ... 다음 호출에 A()
  5. 고토 1

당신이 얻고에서 배열을 방지하는 경우 해제하면 다른 주소에 생성 된 새 배열을 볼 수 있습니다.

my @a; 
for my $i (1..10){ 
    my $ref= &A($i);## the input changes in each round 
    my $ref2= &A(9);## the input is fixed in each round 
    print "$ref\t"; 
    print "$ref2\n"; 
    push @a, $ref, $ref2; 
}