본문 바로가기
개발일지

pintos (부끄러운)실수 기록

by Peter.JH 2023. 12. 14.
728x90

 

여기서 틀린 부분을 찾아보세요. (hint: 2개)

.

.

.

1. check_address 함수를 먼저 살펴보겠습니다.

void check_address(void *addr) {
	struct thread *t = thread_current();
	if (!is_user_vaddr(addr) || addr == NULL || pml4_get_page(t->pml4 , addr) == NULL) {
		exit(-1);
	}
}

seek 함수에서 check_address 함수를 struct file * 타입의 file에 대해 호출하고 있습니다. 하지만 check_address 함수는 void *addr를 매개변수로 받아 해당 주소가 유효한 사용자 주소인지 확인하는 함수입니다. 

 

check_address 함수는 메모리 주소를 받아야 하지만, seek 함수에서는 struct file * 타입의 포인터를 넘겨주고 있습니다. 

확인할 수 없는데 확인하라는 함수를 넣어 오류가 발생했습니다.....

 

2.seek 함수의 반환 타입이 void인 경우, return 문에 값을 포함해서는 안 됩니다. void 함수는 값을 반환하지 않으므로, return 문을 사용할 때도 값을 반환하려고 하면 컴파일 에러가 발생합니다.

 

C언어에서 함수의 반환 타입은 함수가 실행 결과로 어떤 종류의 값을 반환할지 결정합니다. void는 "아무것도 없음"을 의미하므로, void 타입의 함수는 값을 반환하지 않습니다. 따라서 void 타입의 함수 내에서 return 문을 사용할 때 값을 반환하려고 하면, 컴파일러는 이를 오류로 간주합니다. 왜냐하면 이는 함수의 선언(반환 타입이 void임)에 위반되는 행동이기 때문입니다.

 

 

 

포인터 타입

 

 

`strlen` 함수는 `char *` 타입의 인자를 받습니다. 이 함수는 주어진 문자열(즉, `char *` 타입)의 길이를 계산하기 위해 NULL 문자('\0')를 찾아가며 문자를 세는 방식으로 작동합니다. 그러나 `void *` 타입의 포인터는 특정 타입을 가리키지 않습니다. 이는 포인터가 가리키는 메모리의 내용이 어떤 형식으로 해석되어야 하는지에 대한 정보가 없다는 것을 의미합니다. 따라서 `void *` 타입의 인자를 `strlen` 함수에 전달하면, 함수는 어떻게 메모리를 해석하고, 어디에서 문자열이 끝나는지(NULL 문자의 위치)를 알 수 없습니다. 따라서 `void *` 타입의 인자를 `strlen` 함수에 전달하려고 하면, 컴파일러는 타입 불일치 오류를 발생시킵니다. 이는 `strlen` 함수가 `char *` 타입의 인자를 기대하는데, `void *` 타입의 인자가 전달되었기 때문입니다. 이런 오류는 컴파일 시점에 발견되므로, 이를 컴파일 에러라고 합니다. 그렇기 때문에 `void *` 타입의 포인터를 `char *` 타입으로 명시적으로 캐스팅한 후에 `strlen` 함수에 전달해야 합니다. 이렇게 하면 `strlen` 함수는 메모리를 올바르게 해석하고 문자열의 길이를 정확히 계산할 수 있습니다.

 

하지만 없어도 작동은 됩니다....(GCC에서 지원...)

 

 

 

디버거가 없었다면 전혀 신경쓰고 있지 않던 seek함수의 문제점을 찾지 못했을 것이다...

디거버야.. 고마워

728x90

'개발일지' 카테고리의 다른 글

pintos - virtual memory(3)  (0) 2023.12.19
pintos - Virtual Memory(1)  (0) 2023.12.14
Git - Divergent branches  (0) 2023.12.09
pintos - USER PROGRAMS (1)  (0) 2023.12.05
pintos - USER PROGRAMS (intro)  (0) 2023.12.04