Skip to content

Commit

Permalink
fix(blog): Clarify explanation and Fix typos
Browse files Browse the repository at this point in the history
  • Loading branch information
aPatchyDev committed Dec 5, 2024
1 parent 6a42155 commit a5f69bd
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 4 deletions.
8 changes: 4 additions & 4 deletions content/blog/hancell/debug1/index.kr.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ weight = 100

{{% notice style="note" title="주의할 점" %}}
이번 편에서 다루는 `유효범위`란 변수가 잘 정의되어 있는 (well-defined) 범위를 의미한다.
그것이 특수값이든, 참조 시 오류를 던지든, 일정하면 된다.
그것이 특수값이든, 역참조 시 오류를 던지든, 일정하면 된다.
데이터가 실제로 생성되고 폐기되는 정확한 시점인 `수명`은 다음 편에서 다룰 예정이다.
{{% /notice %}}

Expand Down Expand Up @@ -84,13 +84,13 @@ a(은)는 정의되지 않았습니다.
2. 호이스팅은 이루어지지만 정의문 이전에 접근 시 런타임 오류를 던진다 (JS `let`와 동일)
3. 호이스팅이 없어서 실행되기 전에 문법 오류를 던진다.

이 가설들은 [실험1-B][실험1-C]로 검증할 수 있다. `On Error Resume Next`는 VBS의 `try/catch`에 해당한다. 단, 별도의 `catch`가 없어 모든 구문을 개별적으로 `try/catch`로 묶는 셈이다.
이 가설들은 [실험1-B][실험1-C]로 검증할 수 있다. `On Error Resume Next`는 VBS의 `try/catch`에 해당한다. 단, 별도의 `catch` 없이 모든 에러를 무시하고 실행을 이어간다.

가설 #1이 맞을 경우, [실험1-B]에서는 최소한 줄 #3에서 `Test`가 출력이 된 다음에 종료되어야 한다. 그러나 아무런 출력 없이 [실험1-A]와 동일한 오류가 발생하므로 이 가설은 틀렸다.

가설 #2이 맞을 경우, [실험1-C]에서도 오류가 발생해야 한다. 그러나 오류가 발생하지 않고 기본값 (빈 문자열)이 출력되므로 이 가설 또한 틀렸다.

따라서 가설 #3 - 호이스팅이 없다가 정답일 것이다.
따라서 가설 #3 - `호이스팅이 없다` 정답일 것이다.

엄밀히 말하자면 `Superscalar / Out-of-order execution이 없거나 최소한 사용자에게는 그 효과가 노출되지 않는다`는 전제가 깔려있지만 병렬처리하는 것도 아닌 순차 실행에서조차 이 전제를 깨는 프로그래밍 언어는 모르기 때문에 굳이 검증하지는 않겠다.

Expand Down Expand Up @@ -167,7 +167,7 @@ a(은)는 정의되지 않았습니다.
[실험2-A]는 정의되지 않은 변수를 정수와 대소비교를 한 결과를 보여준다. 오류가 나지 않는다는 것만 보인다면 [실험2-C]에서 사용할 수 있으므로 충분하다. 만약 undefined behavior 라고 간주하고 어떤 결과든 발생할 수 있다고 치면 이미 그 시점에서 호이스팅이 없다고 하는 것과 마찬가지다

[실험2-B]는 if문 안에서 선언된 변수가 if문의 상단까지 호이스팅되는지 확인하는 실험이다.
덤으로 [실험1-B]와 비슷하게 해당 블록이 실제로 실행되어야 하는지도 같이 확인한다. 결과는 블록 단위 역시 실행되지 않아도 오류를 던진다.
덤으로 [실험1-B]와 비슷하게 해당 블록이 실제로 실행되어야 오류가 발생하는지도 같이 확인한다. 결과는 블록 단위 역시 실행되지 않아도 오류를 던지는 것으로 보아 호이스팅은 없다.
#3 if 조건절을 위와 같이 작성한 이유는 `if True`가 최적화로 if 블록이 제거되는 것을 방지하기 위해서 값이 런타임에 결정되도록 한 것이다.

[실험2-C]는 if문 안에서 선언된 변수가 if문의 조건절까지 호이스팅되는지 확인하는 실험이다.
Expand Down
8 changes: 8 additions & 0 deletions content/blog/hancell/debug2/index.kr.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,14 @@ Failed to re-use memory
- 리터럴을 쓰지 않고 상위 스코프에서 값을 받아오는 이유는 실험 도중에 불필요한 메모리의 할당과 해제를 줄이기 위해서다
-#6은 디버깅을 위해 해제된 `arr` 변수의 길이 정보가 남아있는 것을 확인한다
-#20~#22는 정말 같은 메모리가 할당된 것을 강조하기 위해 `a->valueY`의 값을 또 다른 임의의 값으로 변경하고 양쪽의 포인터를 통해 역참조하는 엑스트라다

---

사실 memory allocator가 같은 공간을 즉시 재할당하기 위해서는 같은 크기의 메모리를 요청하는 것이 유리하다. 그 이유는 빠른 할당을 위해 대부분의 memory allocator가 크기에 따라 할당할 수 있는 메모리 청크를 스택으로 관리하기 때문이다. 메모리 할당 방법에는 `first fit / best fit` 등의 전략이 있다. 그러나 두 번째에 더 큰 공간을 요청하는 [실험4]는 어느 전략에도 잘 맞지 않는 것처럼 보인다.

아마도 충분히 큰 공간을 할당했기 때문에 파편화된 힙의 앞부분에서는 만족하는 청크가 없어 아직 건드리지 않은 힙 뒷부분에서 청크를 잘라내어 할당하고, 해제된 다음에는 뒷부분과 다시 병합이 됐다가 다시 큰 공간을 요청하자 같은 위치에서 크기만 키운 청크로 다시 잘라내어 할당한 것으로 추측하고 있다.

솔직히 `large chunk`를 재사용해야겠다는 생각으로 첫 배열의 크기만 크게 잡고 두 번째 배열은 적당히 큰 숫자를 넣고 되길래 넘어갔다가 거의 1년이 지나 이 글을 작성하면서 다시 보니 `이게 왜 되지..?` 고민하다 내린 추론이다...
{{% /notice %}}

[실험4]의 줄 #19에서 `arr`의 잔재가 사라진 것을 보면 Dim은 선언 시 초기화하는 것을 알 수 있다.
Expand Down

0 comments on commit a5f69bd

Please sign in to comment.