1

gforth で 2 つの文字列を追加しようとしていますが、恐ろしいエラー メッセージが表示されます。

正常にs" foo" s" bar" append type cr動作しますが、変数に文字列を格納したり、単語から文字列を作成したりするとすぐにエラーが発生します。例えば:

: make-string ( -- s )
    s" foo" ;

: append-print ( s s -- )
    append type cr ;

make-string s" bar" append-print

実行すると、次のエラーが発生します。

$ gforth prob1.fs -e bye
gforth(41572,0x7fff79cc2310) malloc: *** error for object 0x103a551a0: pointer being realloc'd was not allocated
*** set a breakpoint in malloc_error_break to debug

Abort trap: 6.

私は C に精通しているので、Forth の使い方が間違っていることは明らかです。Fore でのメモリ管理について、非常に基本的なことを学ぶ必要があると思います。

ここで何が問題なのか、どうすればよいのか、誰か説明してもらえますか?

変数に格納されている文字列を追加しようとすると、問題が発生します。

variable foo
s" foo" foo !

foo s" bar " append type cr

これは、私が壊さなければならないループで終わります:

$ gforth prob2.fs
foo��^C
in file included from *OS command line*:-1
prob2.fs:4: User interrupt
foo s" bar " append >>>type<<< cr
Backtrace:
$10C7C2E90 write-file

参考までに、私は Mac OS X で gforth 0.7.2 を使用しています。

アップデート

の定義を見ることができますappend

see append
: append
  >l >l >l >l @local0 @local1 @local3 + dup >l resize throw >l @local4 @local0 @local3 + @local5
  move @local0 @local1 lp+!# 48 ; ok

では、Forth で自分でメモリを管理する必要があるように見えますか? もしそうなら、どのように?

解決

Andreas Bombe が以下の手がかりを提供します。動作する最終的なプログラムは次のようになります

: make-string ( -- s )
  s" foo" ;

: append-print
  s+ type cr ;

make-string s" bar" append-print

出力は

$ gforth b.fs -e bye
foobar
4

2 に答える 2

1

append最初の文字列で make space を使用resizeして、2 番目の文字列を追加します。これには、文字列をヒープに割り当てる必要があります。

文字列を単語にコンパイルするとs"、辞書に割り当てられます。resizeそのポインターで(直接または間接的に)しようとappendすると、表示されるエラーが発生します。

通常s"、未定義の解釈セマンティクスがあります。Gforth では、便宜上、文字列をヒープに割り当てるという解釈セマンティクスを定義しています。そのため、コンパイルしない限り (gforth で) 動作します。

編集:

の定義を見つけました。これは(外部関数インターフェイス ビルダーのように見えます)appendの一部であり、標準的な単語ではありません。libcc.fsこれはソース内の定義であり、逆コンパイルよりも読みやすいsee:

: append { addr1 u1 addr2 u2 -- addr u }
    addr1 u1 u2 + dup { u } resize throw { addr }
    addr2 addr u1 + u2 move
    addr u ;

その直前に の定義がありs+ます。

: s+ { addr1 u1 addr2 u2 -- addr u }
    u1 u2 + allocate throw { addr }
    addr1 addr u1 move
    addr2 addr u1 + u2 move
    addr u1 u2 +
;

ご覧のとおり、これは最初の文字列のサイズを変更する代わりに新しいメモリ空間を割り当て、両方の文字列を連結します。代わりにこれを使用できます。ただし、これは標準的な単語ではなく、たまたまlibcc.fsin gforth の内部実装の詳細として環境にあるため、他の場所で利用できることに依存することはできません。

于 2014-04-25T23:34:40.393 に答える