2014-04-20 1 views
1

gforth에서 두 개의 문자열을 추가하려고하는데 무서운 오류 메시지가 표시됩니다.단어 또는 변수의 문자열을 추가 할 때 오류가 발생했습니다.

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 

는 다음과 같은 오류 생산 실행 : 내가 아니라 C에 정통하고있어

$ 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. 

를, 그래서 내가 넷째 잘못 사용하고 꽤 분명한 것 같다! Forth에서 메모리 관리에 관해 아주 기본적인 것을 배워야한다고 가정합니다.

아무도 설명이 잘못되었다고 설명 할 수 있습니까? 이되어야합니까?

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에서 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 

를, 내가 로한 메모리 나 자신을 관리하는 데 필요한 것 같다? 그렇다면 어떻게?

솔루션

안드레아스 봄베는 아래의 단서를 제공한다. 작동 마지막 프로그램은

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

: append-print 
    s+ type cr ; 

make-string s" bar" append-print 

출력이

$ gforth b.fs -e bye 
foobar 

답변

1

append는 첫 번째 문자열에 resize를 사용하다 공간이 두 번째 문자열을 추가 할 수 있도록 할 것이다. 이를 위해서는 문자열을 힙에 할당해야합니다.

s"으로 문자열을 컴파일하면 단어가 사전에 할당됩니다. 해당 포인터에서 resize (직접 또는 간접적으로 append 통해)을 시도하면 오류가 표시됩니다.

일반적으로 s"에는 정의되지 않은 해석 의미가 있습니다. Gforth는 힙에 문자열을 할당하는 것으로 편의상 해석 의미를 정의합니다. 이것이 컴파일하지 않는 한 (gforth에서) 작동하는 이유입니다.

편집 :

나는 그것을 libcc.fs (가 보인다 외국인 함수 인터페이스 빌더)이 아닌 표준 단어의 일부, append의 정의를 발견했습니다. 이것은 see 디 컴파일보다 더 많은 읽을 수있는 소스의 정의입니다 :

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

이 하나가 아닌 새로운 메모리 공간을 할당 볼 수 있듯이 : 그 전에 즉시

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

것은 s+의 정의입니다 첫 번째 문자열의 크기를 조정하고 두 문자열을 연결합니다. 대신이 것을 사용할 수 있습니다. 표준 단어가 아니며 gforth의 내부 구현 세부 사항 인 libcc.fs으로 사용자 환경에있을 수 있으므로 다른 곳에서 사용할 수는 없습니다.

+0

큰 설명 주셔서 감사합니다. 그러나 위 예제를 어떻게 작성할 수 있을지에 대한 제안이 있습니까? 먼저 문자열을 생성하기 위해서'CREATE'를 사용해야합니까? (내가 원한다면 기꺼이 해답을 받아 들일 수 있습니다. 어쨌든 받아들이겠습니다.하지만 사이트에 좋을 것입니다.) – csl

+1

@csl 뭔가를 발견하고 내 대답을 편집했습니다. . –