이전 주제 보기 :: 다음 주제 보기 |
글쓴이 |
메시지 |
신기정
가입: 2009년 9월 15일 올린 글: 83
|
올려짐: 2010년10월3일 10:47 주제: StackOverFlow와 관련하여 |
|
|
numch함수에서 5000 만 넘어가더라도 스택 오버플로가 발생합니다.
제가 numch 코드를 제대로 짠 것인지 지금으로서는 확신이 서지 않습니다만
아마도
메모리를 할당할 수만 있고 반환할 수가 없어 지나치게 매모리가 낭비되기 때문에
저런 문제가 발생하는 것같습니다.
대표적인 곳이 LETV와 CALLV인데요.
LETV 스코프가 끝나는 곳에서, 선언된 변수를 해제하고
CALLV 스코프가 끝나는 곳에서, 매개변수들이 차지하는 메모리를 해제한다면
오버플로를 어느 정도 막을 수 있다고 생각합니다.
그런데 이부분을 수정하는 것은 뼈대코드에 해당하는 부분이어서
조교님의 의견을 묻고 싶습니다.
더불어 다른 분들 의견도 궁금하고,
numch함수가 저의 경우처럼 5000만 넘어가도 스택오버플로가 발생하는지도 궁금합니다. |
|
위로 |
|
 |
신기정
가입: 2009년 9월 15일 올린 글: 83
|
올려짐: 2010년10월4일 21:07 주제: 아.. |
|
|
오래 찾아본 끝에 스택 오버플로우가 발생하는 이유를 찾았습니다.ㅜㅜ
K- 언어는 스택을 반환하지 않으므로 재귀적으로 수행하다보면
전체 메모리 사이즈가 크게 증가합니다.
저같은 경우는
nmuch(5000)을 수행하였을 때
Mem에 20만 개 정도의 데이터가 저장되는 것을 확인할 수 있었습니다.
이렇게 메모리를 많이 사용하고 있는 상황에서
Mem의 base 주소(0) 근처의 데이터를 접근할 경우
recursive하게 구현되어있는 Mem.replace_nth 함수를 20만번 호출해야합니다.
여기서 스택 오버플로가 발생합니다.
현재의 Mem 모듈을 하에서는
이런 것을 피해서 k-프로그래밍을 하시면 저같은 삽질은 하지 않으시겠네요 ㅜㅜ
즉 nmuch(5000) 호출을 중심으로 이전과 이후를 나누었을 때
'이후 부분'에서 '이전 부분'에서 정의한 변수들을 참조하면 문제가 생깁니다.
내 일요일 ㅜㅜㅜㅜ |
|
위로 |
|
 |
최종욱
가입: 2009년 9월 15일 올린 글: 84
|
올려짐: 2010년10월4일 22:42 주제: |
|
|
임시방편으로 OCAML RUN 시 스택 크기를 설정하는 방법이 있습니다.
코드: | $ export OCAMLRUNPARAM='l=50M' |
(확인 : env)
처럼 스택 크기를 늘려서(?) 실행하면 오버플로우가 안 날듯한데...
자세한 것은 man ocamlrun 에...
이건 K- 랭기지의 문제라기보다는 Mem과 Env를 구현하는 방식..의 문제인 것 같아서 수강생이 고려해야할 문제의 영역이 아니라고 생각합니다. _________________ Jongwook Choi
Seoul National University, School of Computer Science & Engineering |
|
위로 |
|
 |
안준환
가입: 2010년 9월 2일 올린 글: 12
|
올려짐: 2010년10월4일 23:46 주제: |
|
|
스택 넘침이 발생하는 원인이 Mem.replace_nth 함수의 재귀 호출로 인한 것이라면 이 함수를 끝 재귀(tail recursion)의 형태로 바꾸어 주는 것도 해결책이 될 수 있습니다.
코드: | let rec replace_nth = fun l n c ->
match l with
h::t -> if n = 1 then c::t else h::(replace_nth t (n-1) c)
| [] -> raise Not_allocated
|
주어진 뼈대 코드의 구현은 이와 같이 되어 있어서 끝 재귀가 아닙니다. 이를 다음과 같이 바꾸면 끝 재귀의 형태가 되어서 상수 스택 크기만으로도 재귀 호출을 수행할 수 있습니다.
코드: | let replace_nth l n c =
let rec accumulate l n acc =
match l with
| _ :: t when n = 1 -> List.rev_append acc (c :: t)
| h :: t -> accumulate t (n - 1) (h :: acc)
| [] -> raise Not_allocated
in
accumulate l n []
|
다만 이로 인해 문제가 일부 해결되었더라도 주어진 semantics 함수가 이미 끝 재귀가 아니기 때문에 이로 인해서 큰 입력에 대해 여전히 스택 넘침이 발생할 수 있습니다. |
|
위로 |
|
 |
|