Taking baby-developer steps

2022.04.09. push_swap 파싱부 구현 -4 arr4i에 입력값을 오름차순으로 정렬하면서 넣기 -2, 스택구현 본문

Logs/학습 log

2022.04.09. push_swap 파싱부 구현 -4 arr4i에 입력값을 오름차순으로 정렬하면서 넣기 -2, 스택구현

Surin Lee 2022. 4. 9. 15:29

 

arr4i에 오름차순으로 정렬하는데 있어서 sigfault가 자꾸 발생하는데, sort4i 함수에 swap_int 함수 호출 전에 printf()를 한번 이상 호출하면 sigfault 없이 의도한 결과가 출력되는 기 현상을 발견했고 , 이를 해결하기 위해 결국 lldb로 디버깅을 시작했다.

 입력값은 "2" "1" "0" 순으로 넣었고, sort4i(arr4i를 정렬하기 위한 함수)내에 int형 포인터 2개를 인자로 받아 두개의 값을 swap하는 함수(k=1일 때("2"만 들어있던 arr4i 내에 "1"을 인덱스 1의 자리에 넣고, 오름차순 정렬을 위해 인덱스 0의 자리에 있는 "2"와 자리를 바꿀 때) swap_int에서 EXC_BAD_ACCESS (code=1, address=0x0)이 발생함을 확인했다.

 int형 포인터인 temp가 가리킬 메모리 주소를 지정해 주지 않은 채로 값을 저장하려고 했기 때문에 발생한 오류였다. swap_int가 int형 포인터를 파라미터로 받으니 통일 시킬겸 임시 저장소 temp도 int형 포인터로 별 생각없이 선언했는데, 생각해보니 포인터에게 가리킬 주소를 설정하지 않은채(쓰레기 값이 들어가서 임의의 아주 중요한 주소를 가리키게 된 상태일 수도 있는데도...!!!!) 어딘지도 모르는 주소값 내의 값을 바꾸려고 했다니.. 너무 초보적인 실수 때문에 디버깅 하느라 시간을 많이 썼다! 처음 포인터를 배울 때 부터 주의사항이라고 그렇게 봐놓고선..! 한 생각에 갇히면 이렇게 초보적인 실수도 하게 되는것 같다. 조심하고, 한 생각에 갇히지 않게 스스로를 상기시켜야겠다.

swap_int 내에서 임시로 값을 저장하는 temp를 int형 포인터에서 단순 int형으로 바꾸어주었다. 그 결과 정상적으로 작동함을 확인했다.

 

+ 하나의 argv 스트링에 여러개의 변수가 들어올 때, 처리할 때 인덱스 처리에 약간의 오류(변수를 상수로 착각해서)가 있어서 수정했고, 이후 정상적으로 잘 작동함을 확인 하였다.

 

이로써 과제에서 요구한

1. digit이 아닌 경우

2. 중복인 수가 들어온 경우

3. int 범위를 넘어서는 경우

4. " "가 입력값으로 들어오는 경우

에러 메세지인 "Error\n"를 출력하며 exit(1)로 프로그램을 종료하는 파싱부를 구현했다.

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

이제 파싱과 동시에, 스택으로 쓸 구조체(스택 a가 될 것임)에 들어오는 순서대로 입력값을 저장하고, 입력값을 모두 받아들이고 나면 오름차순으로 정렬이 끝난 arr4i에서 찾아 해당 값의 index 값을 스택 노드 내 정보에 저장 할 것이다. 이 index 값을 기준으로 스택을 정렬할것이기때문. 또, 이로 인해 중간값(피봇값)을 정확히 알수 있게 되었다. (총 들어온 input의 갯수) / 2를 하면 되기 때문에, 앞서 구상했던 것처럼 표본집단을 만들어 평균을 낼 필요가 없어졌다.

 

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

스택a, b 및 관련 명령어(연산)를 만들기 위해 구상한, 가장 기본이 되는 양방향 연결리스트 관련 함수의 대략의 명세이다.

이번 과제에서 스택을 구현하는데 "양방향 연결리스트" 자료구조를 사용하기로 결정한 이유는, 과제에서 요구하는 스택이 말로만 스택이지, 거의 "덱"과 같은 연산이 필요하기 때문이다.(ra, rb, rr, rra, rrb, rrr등) 정말 정석 스택처럼 연산이 들어갔다면 간편하게 배열을 사용했을거 같다. 

구현 도중 is_empty_s(스택이 비었는지 확인 하는 함수)는 굳이 필요 없다고 생각했다. 비어 있는 경우

스택 초기화 시 처럼 top_index값을 -1로 두고 확인할 수 있을것 같아서 이다. 대신 구현하던 도중 연결리스트에 연결할 새로운 new node를 할당하고 초기화할 함수 ft_lstnew 를 추가했다.

연결리스트에 연결할 노드들에는 각각 content와 arr4i에서의 index 정보가 담길 것이기 때문에, 저장할 값 content, 그리고 해당 값을 탐색할 arr4i 배열을 인자로 받았다.

Comments