이 문서는 제 삽질과 해당 프로젝트를 풀기 위한 과정을 기록한 문서입니다. 코딩과 문서를 병행으로 작성하기에, 맞지 않는 지식이 난무할 수 있어 정답 참고용으로는 부적합하다는 것을 알아주세요.
일단 read파일의 정확한 작동원리를 알아야겠다고 생각해, 간단히 테스트 코드를 짜 보았다.
테스트를 하면서 몇가지 안 것이 있는데,
1.변수 fd는 open함수가 fd테이블 몇번에 존재하는지 알려주는 단순한 정수타입 변수다.
테이블 몇번에 위치해있는지 안다면, 이는 숫자로 대체 가능하다.
2.해당 파일의 읽어진 정도는 file table에서 보관하고 있다.
3.같은 파일을 두번 open해도 이들은 각각 다른 fd를 가진다.
그런데 테스트를 하다가 또 신기한 점을 발견했다.
하나의 배열이 fd에 접근하는 것은 괜찮았지만, 두개의 배열이 같은 fd를 read하는것은 이상이 발생했었다.BUFFER_SIZE는 4로 설정했다.
하나의 배열만 사용한 경우
문제없이 4개씩 잘 읽어온다.
문제의 두개를 사용한 경우
문제1. 4바이트씩 잘 읽어오던 temp1이 왜 갑자기 6개씩, 두번째 호출때는 8개씩 읽어오는가?
문제2. 왜 temp2의 메모리 주소를 temp1이 침범하는가?
이 문제에 대해 한 분이 조언을 해주셨다.
suhong님의 말씀에 따르면, 정확하게 \0처리를 해주지 않는 한, 메모리 바깥영역에 null이 있을지 없을지는 모른다. 그렇기에 temp의 영역을 읽으면서 인접해있는 temp2에 메모리까지 읽은 것이라고 설명해주셨다.
그런데 문제는
요 사진의 첫번째 출력부분이다. 세번째 출력은 방금 설명한대로 temp1이 메모리를 읽던 중 침범했다고 하지만, 첫번째는 왜??? 6바이트를 출력하냐는 것이다. 그런데 temp2는 또 멀쩡히 4바이트를 읽어오고 있고.
이것 또한 슬랙에서 명쾌한 해답이 나왔다.
메모리 주소의 \0를 처리하지 않았기 때문이었다. 배열이 메모리의 할당되는 위치에 대한 인과관계는 둘째치고, 선언된 지역변수인 배열이 깨끗하게 초기화되어있을것이라는 보장은 없다.
이 말은 즉슨, 해당 배열에서 어디까지가 출력 가능한 범위인지 정해주지 않았기에 출력시 다른 범위에 존재하는 값이 튀어나올 수 있다는 것이다. 이것에 대한 처리로 버퍼사이즈 + 1 및 마지막에 \0를 넣는 것으로 깔끔하게 해결됐다.
야호!!!
근데 gnl 진도 언제나가지...