확인 malloc에 대한 답변이 이미 게시되었습니다.
더 흥미로운 부분은 자유 가 어떻게 작동 하는가입니다 (이 방향에서 malloc도 더 잘 이해할 수 있습니다).
많은 malloc / free 구현에서 free는 일반적으로 메모리를 운영 체제로 반환하지 않습니다 (또는 드문 경우에만). 그 이유는 힙에 공백이 생겨서 2GB 또는 4GB의 가상 메모리를 공백으로 마무리하기 때문입니다. 가상 메모리가 완료 되 자마자 큰 어려움에 처하게되므로 피해야합니다. 다른 이유는 OS가 특정 크기와 정렬을 가진 메모리 청크 만 처리 할 수 있기 때문입니다. 구체적으로 말하면 : 일반적으로 OS는 가상 메모리 관리자가 처리 할 수있는 블록 만 처리 할 수 있습니다 (대개 512 바이트의 배수 (예 : 4KB)).
따라서 40 바이트를 OS로 반환하면 작동하지 않습니다. 그래서 무료는 무엇을 하는가?
Free는 메모리 블록을 자체 빈 블록 목록에 넣습니다. 일반적으로 주소 공간에서 인접한 블록을 함께 병합하려고 시도합니다. 사용 가능한 차단 목록은 시작 부분에 관리 데이터가있는 순환 메모리 청크 목록입니다. 이것이 표준 malloc / free로 매우 작은 메모리 요소를 관리하는 것이 효율적이지 않은 이유이기도합니다. 모든 메모리 청크에는 추가 데이터가 필요하며 크기가 작을수록 조각화가 더 많이 발생합니다.
자유 목록은 또한 새로운 메모리 청크가 필요할 때 malloc이 보는 첫 번째 장소입니다. OS에서 새 메모리를 호출하기 전에 스캔됩니다. 필요한 메모리보다 큰 청크가 발견되면 두 부분으로 나뉩니다. 하나는 발신자에게 반환되고 다른 하나는 다시 무료 목록으로 돌아갑니다.
이 표준 동작에 대한 여러 가지 최적화가 있습니다 (예 : 작은 메모리 청크). 그러나 malloc과 free는 매우 보편적이어야하기 때문에 대안을 사용할 수없는 경우 표준 동작은 항상 폴백입니다. 또한 프리리스트를 처리 할 때 최적화가 있습니다 (예 : 크기별로 정렬 된 목록에 청크 저장). 그러나 모든 최적화에는 자체 제한이 있습니다.
왜 코드가 충돌합니까?
그 이유는 4 개의 문자로 된 영역에 9 개의 문자 (후미 널 바이트를 잊지 마십시오)를 쓰면 데이터 청크 뒤에 "다른"메모리에 저장된 관리 데이터를 덮어 쓰게되기 때문입니다 ( 이 데이터는 대부분 메모리 청크의 "앞에"저장되므로). 그러면 free가 청크를 free list에 넣으려고 할 때이 관리 데이터를 건 드리면 덮어 쓴 포인터 위로 넘어 질 수 있습니다. 시스템이 중단됩니다.
이것은 다소 우아한 행동입니다. 또한 어딘가에 런 어웨이 포인터가 memory-free-list의 데이터를 덮어 쓰고 시스템이 즉시 충돌하지는 않지만 나중에 일부 서브 루틴이 발생하는 상황을 보았습니다. 중간 정도의 복잡한 시스템에서도 이러한 문제는 실제로 디버깅하기가 매우 어려울 수 있습니다! 내가 관여했던 한 경우, 메모리 덤프에 표시된 것과 완전히 다른 위치에 있었기 때문에 충돌의 원인을 찾는 데 며칠이 걸렸습니다. 시한 폭탄과 같습니다. 다음 "무료"또는 "멀록"이 충돌하지만 그 이유를 모릅니다.
이것들은 최악의 C / C ++ 문제 중 하나이며 포인터가 그렇게 문제가 될 수있는 한 가지 이유입니다.