サブルーチンのローカル変数と引数の終了No.09853
fzok4234 さん 22/04/20 23:12
 
毎度お世話になっております。


さて、マクロ変数用のメモリ領域について少し分からないことがあります。call 文
で呼び出す
サブルーチンの中の、
 $$string
 ##numeric
とかのローカル変数や、
 ##1
 $$2
とかの引数に割り当てられたメモリ領域は、サブルーチンを return ; で終了させた
ら速やかに
解放されるのでしょうか ?

変数用メモリ領域の上限が最大で 64MB と手狭な中で、もしローカル変数と引数に割
り当てられた
メモリがマクロ全体の終了まで居座り続ければ、大量のサブルーチンの使用の際にメ
モリリークが
発生してしまい、メインのグローバル変数の容量がどんなに少なくても変数用メモリ
が枯渇して
しまいます。

例えば、文末に掲示したような極端なケースの場合、もしメモリリークがあればあっ
という間に
メモリ不足のエラーとなってしまいます。

現実には、1 つのマクロにサブルーチンを万単位で作ることはまずありません。しか
し実際の運用では、
同じシグネチャで中身の異なるサブルーチンの「配列」を数十 〜 数百個単位で用意
して、その
サブルーチンの名前文字列値を「関数ポインター」のように扱って状況に応じて呼び
出すサブルーチンを
切り替える、ということはよくあります。

今のところ、万単位でサブルーチンを書く作業が大変なため、当方でテストはまだ行
っていません。
また、当方で実際に使用しているマクロでもメモリ不足のエラーにはまだ出くわして
いません。

しかし、サブルーチンの終了でのメモリ開放が正しく実装されているのか、それとも
メモリリークが
本当に存在しているのか当方で把握し切れていないため、今後マクロに新しいサブ
ルーチンを追加しただけで
メモリ不足のエラーが起きないかどうか不安なところでございます。

ローカル変数と引数のメモリ管理に関する詳細な説明を、どうかよろしくお願い申し
上げます。


debuginfo 2 ;

#index = 0 ;
while ( #index < 65536 ) {
    $delegate = @"Function_" + str( #index ) ;
    call $delegate
            #index
        ,       @"寿限無寿限無五劫の擦り切れ海砂利水魚の水行末雲来末風来末食
う寝る処に住む処"
            +   @"藪ら柑子の藪柑子パイポパイポパイポのシューリンガンシューリ
ンガンのグーリンダイ"
            +   @"グーリンダイのポンポコピーのポンポコナの長久命の長助"
    ;
   
    #index = #index + 1 ;
}

endmacro ;

Function_0
    $$value = str( ##1 ) + @" : " + $$2 ;
    debuginfo $$value + "\U0000000A" ;
    return $$value ;

Function_1
    $$value = str( ##1 ) + @" : " + $$2 ;
    debuginfo $$value + "\U0000000A" ;
    return $$value ;

Function_2
    $$value = str( ##1 ) + @" : " + $$2 ;
    debuginfo $$value + "\U0000000A" ;
    return $$value ;

// .... 以下繰り返し。....

Function_65534
    $$value = str( ##1 ) + @" : " + $$2 ;
    debuginfo $$value + "\U0000000A" ;
    return $$value ;

Function_65535
    $$value = str( ##1 ) + @" : " + $$2 ;
    debuginfo $$value + "\U0000000A" ;
    return $$value ;



[ ]
RE:09853 サブルーチンのローカル変数と引No.09854
こみやんま さん 22/04/21 00:45
 
call してreturnした後、ローカル変数は消える(解放)されるものの、別のユーザー
関数をcallしない限り、$$result の分がずっとマクロ終了までは残るので、
メモリ残量は予期しにくいでしょうね。

-----------------------------------------------------------------------
$a = R"RAW(
飛騨プラネタリウムは、岐阜県高山市にあるプラネタリウムである。高山市の条例上
の名称は高山市飛騨プラネタリウムである。飛騨地域唯一のプラネタリウムであり、
科学および科学技術に関する知識の普及および啓発を図ることを目的とした施設であ
る。……
遠州&#24553;劇とは、永禄5年(1562年)から同9年(1566年)にかけて発生した、遠
江国内の主に天竜川流域における複数の国衆による駿河今川氏への大規模な叛乱のこ
とである。戦国期の遠江国は駿河今川氏の侵攻を受け、永正14年(1517年)に今川氏
親が遠江守護である斯波氏を打ち破り、……
流星クラスター現象は、発見者の名前から木下現象とも呼ばれ、短時間に多数の流星
が集中的に流れる現象である。1997年に、しし座流星群の観測を行っていた日本流星
研究会の木下正雄らが初め
飛騨プラネタリウムは、岐阜県高山市にあるプラネタリウムである。高山市の条例上
の名称は高山市飛騨プラネタリウムである。飛騨地域唯一のプラネタリウムであり、
科学および科学技術に関する知識の普及および啓発を図ることを目的とした施設であ
る。……
遠州&#24553;劇とは、永禄5年(1562年)から同9年(1566年)にかけて発生した、遠
江国内の主に天竜川流域における複数の国衆による駿河今川氏への大規模な叛乱のこ
とである。戦国期の遠江国は駿河今川氏の侵攻を受け、永正14年(1517年)に今川氏
親が遠江守護である斯波氏を打ち破り、……
流星クラスター現象は、発見者の名前から木下現象とも呼ばれ、短時間に多数の流星
が集中的に流れる現象である。1997年に、しし座流星群の観測を行っていた日本流星
研究会の木下正雄らが初め
飛騨プラネタリウムは、岐阜県高山市にあるプラネタリウムである。高山市の条例上
の名称は高山市飛騨プラネタリウムである。飛騨地域唯一のプラネタリウムであり、
科学および科学技術に関する知識の普及および啓発を図ることを目的とした施設であ
る。……
遠州&#24553;劇とは、永禄5年(1562年)から同9年(1566年)にかけて発生した、遠
江国内の主に天竜川流域における複数の国衆による駿河今川氏への大規模な叛乱のこ
とである。戦国期の遠江国は駿河今川氏の侵攻を受け、永正14年(1517年)に今川氏
親が遠江守護である斯波氏を打ち破り、……
流星クラスター現象は、発見者の名前から木下現象とも呼ばれ、短時間に多数の流星
が集中的に流れる現象である。1997年に、しし座流星群の観測を行っていた日本流星
研究会の木下正雄らが初め
飛騨プラネタリウムは、岐阜県高山市にあるプラネタリウムである。高山市の条例上
の名称は高山市飛騨プラネタリウムである。飛騨地域唯一のプラネタリウムであり、
科学および科学技術に関する知識の普及および啓発を図ることを目的とした)RAW";

$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;

call Function_0 $a;
endmacro;

Function_0:
return $$1+$$1;

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

最後の$$1+$$1を、$$1 にするとメモリは溢れない。

[ ]
RE:09854 サブルーチンのローカル変数と引No.09855
fzok4234 さん 22/04/21 10:36
 
こみやんまさん、調査ありがとうございます。


一応、ローカル変数と引数はサブルーチン終了後にちゃんと破棄されるとのことで安
心しました。


> $a = $a + $a ;
> $a = $a + $a ;
> $a = $a + $a ;
> ...

容量をわざと指数関数的に爆発させるために、このような方法があったのだと、目か
ら鱗が落ちる
思いです。



[ ]
RE:09855 サブルーチンのローカル変数と引No.09857
秀丸担当 さん 22/04/21 18:24
 
私のほうからもコメントしておくと、サブルーチンをreturnして終わったら、ローカ
ル変数は消去されることになっています。

[ ]