IT이야기

C에서 무료와 몰록은 어떻게 작동하는가?

cyworld 2022. 4. 16. 09:50
반응형

C에서 무료와 몰록은 어떻게 작동하는가?

예를 들어 "중간에서" 포인터를 떼어내려고 하면 어떻게 되는지 알아내려고 하는데, 다음 코드를 보십시오.

char *ptr = (char*)malloc(10*sizeof(char));

for (char i=0 ; i<10 ; ++i)
{
    ptr[i] = i+10;
}
++ptr;
++ptr;
++ptr;
++ptr;
free(ptr);

처리되지 않은 예외 오류 msg와 충돌한다.사용법뿐만 아니라 이상한 오류와 예외를 이해하고 코드를 더 잘 디버깅할 수 있도록 무료 작동 원인과 방법을 이해하고 싶다.

고마워요.

당신이 블록을 만들 때, 그것은 실제로 당신이 요청한 것보다 더 많은 메모리를 할당한다.이 여분의 메모리는 할당된 블록의 크기, 그리고 다음 자유/사용 블록에 대한 링크와 같은 정보를 블록의 체인에 저장하는 데 사용되며, 때로는 할당된 블록의 끝을 지나 작성하면 시스템이 탐지할 수 있도록 도와주는 "보호 데이터"도 사용된다.또한 대부분의 할당자는 전체 크기 및/또는 메모리 부분의 시작을 바이트의 배수로 반올림할 것이다(예: 64비트 시스템의 경우 정렬되지 않은 주소에서 데이터에 액세스하는 것이 프로세서/버스의 경우 더 어렵고 비효율적일 수 있으므로 데이터를 64비트(8바이트)의 배수로 정렬할 수 있다). 따라서 사용자는 어떤 "패딩"으로 끝날 수도 있다.(212바이트).

포인터를 해제하면 해당 주소를 사용하여 할당된 블록의 시작 부분(일반적으로)에 추가된 특수 정보를 찾으십시오.다른 주소로 전달하면 가비지가 들어 있는 메모리에 액세스하여 가비지의 동작이 정의되지 않음(그러나 가장 자주 충돌)

나중에 블록을 해제()하지만 포인터를 "잊지" 않으면 나중에 우연히 해당 포인터를 통해 데이터에 액세스하려고 할 수 있으며, 동작이 정의되지 않는다.다음과 같은 상황이 발생할 수 있다.

  • 메모리는 자유 블록 목록에 저장될 수 있으므로, 메모리에 액세스할 때, 거기에 남겨둔 데이터가 계속 들어 있고, 코드는 정상적으로 실행된다.
  • 메모리 할당자가 당신의 프로그램의 다른 부분에 메모리를 주었을 수도 있고, 그것은 아마도 당신의 이전 데이터를 덮어쓰게 될 것이다. 그래서 당신이 그것을 읽을 때, 당신은 당신의 코드로부터 예기치 않은 행동이나 충돌을 야기할 수 있는 가비지를 얻을 것이다.아니면 다른 데이터 위에 글을 써서 미래의 어느 시점에서 프로그램의 다른 부분이 이상하게 행동하게 할 것이다.
  • 메모리는 운영 체제에 반환될 수 있었다(더 이상 사용하지 않는 메모리의 "페이지"는 주소 공간에서 제거할 수 있으므로, 해당 주소에서 더 이상 사용할 수 있는 메모리가 없음 - 기본적으로 응용프로그램 메모리에 사용되지 않는 "구멍").응용 프로그램이 데이터에 액세스하려고 하면 하드 메모리 오류가 발생하고 프로세스가 중단된다.

따라서 포인터가 가리키는 메모리를 확보한 후 포인터를 사용하지 않도록 하는 것이 중요하다. 가장 좋은 방법은 메모리를 확보한 후 포인터를 NULL로 설정하는 것이다. NULL 포인터를 쉽게 테스트할 수 있고, NULL 포인터를 통해 메모리에 액세스하려고 하면 불량하지만 일관된 동작이 발생하기 때문에 디버깅이 훨씬 쉽다.

대부분의 (전부는 아닐 경우) 구현은 조작하고 있는 실제 포인터 몇 바이트 전에 데이터 양을 검색하여 여유 공간을 확보한다.난폭한 짓을 하다.free메모리 맵이 손상될 것이다.

예를 들어, 10바이트의 메모리를 할당할 때 시스템은 실제로 14바이트를 예약한다.처음 4개에는 요청한 데이터 양(10개)과 그 다음 반환 값이 들어 있다.malloc할당된 14개의 사용되지 않은 데이터의 첫 번째 바이트에 대한 포인터.

전화할 때free이 포인터에서, 시스템은 원래 14바이트를 할당했다는 것을 알기 위해 4바이트를 거꾸로 조회할 것이다.이 시스템은 무료 데이터 양을 추가 매개 변수로 제공하는 것을 방지한다.free그 자체로

다른 도 있다, 다다다.malloc/free이것을 성취하기 위한 다른 방법을 선택할 수 있다.하지만 그들은 일반적으로 다음을 지지하지 않는다.free에 의해 반환된 것과 다른 포인터 위에.malloc또는 동등한 기능.

당신은 아마도 당신이 받은 포인터를 정확히 돌려주어야 한다는 것을 알고 있을 것이다.

free()는 처음에는 당신의 블록이 얼마나 큰지 모르기 때문에, 주소에서 원래의 블록을 식별한 다음 그것을 자유 리스트로 되돌리기 위해서는 보조 정보가 필요하다.그것은 또한 더 가치 있는 큰 자유 블록을 생산하기 위해 이웃들과 작은 자유 블록들을 병합하려고 노력할 것이다.

궁극적으로 할당자는 블록에 대한 메타데이터를 가지고 있어야 하며, 최소한 그 길이를 어딘가에 저장해야 한다.

나는 이것을 하는 세 가지 방법을 설명할 것이다.

  • 분명한 한 장소는 반환된 포인터 바로 앞에 그것을 보관하는 것이다.요청된 것보다 몇 바이트 더 큰 블록을 할당하고 첫 번째 단어에 크기를 저장한 다음 두 번째 단어에 대한 포인터를 반환할 수 있다.

  • 또 다른 방법은 주소를 키로 사용하여 적어도 할당된 블록의 길이를 설명하는 별도의 지도를 유지하는 것이다.

  • 구현은 주소와 지도에서 일부 정보를 얻을 수 있다.더 4.3BSD 커널 할당자("McKusick-Karel 할당자"라고 함)는 페이지 크기보다 작은 개체에 대해 2개의 권한을 할당하고 페이지당 크기만 유지하여 지정된 페이지의 모든 할당을 단일 크기로 만든다.

어떤 구현으로 인해 런타임이 소모될지는 의문이지만, 두 번째 유형과 세 번째 유형의 할당자가 실제로 포인터와 DTRT를 발전시켰다는 것을 감지하는 것이 가능할 것이다.

절대 이러지 마.

주소를 잘못 입력하셨네요.ptr 값을 변경하여 주소를 변경하십시오.free는 4바이트부터 시작하는 블록을 free로 해야 한다는 것을 알 방법이 없다.원래 포인터를 그대로 유지하고 조작한 포인터가 아닌 포인터를 자유롭게 유지하십시오.다른 사람들이 지적했듯이, 당신이 하고 있는 일의 결과는 "정의되지 않았다"...따라서 다루지 않은 예외.

주소를 잘못 입력하셨네요.ptr 값을 변경하여 주소를 변경하십시오.free는 4바이트부터 시작하는 블록을 free로 해야 한다는 것을 알 방법이 없다.원래 포인터를 그대로 유지하고 조작한 포인터가 아닌 포인터를 자유롭게 유지하십시오.다른 사람들이 지적했듯이, 당신이 하고 있는 일의 결과는 "정의되지 않았다"...따라서 다루지 않은 예외.

출처: http://opengroup.org/onlinepubs/007908775/xsh/free.html

자유() 함수는 ptr이 가리키는 공간을 할당 해제하게 한다. 즉, 추가 할당을 위해 사용할 수 있게 한다.ptr이 null 포인터일 경우 아무런 조치도 일어나지 않는다.그렇지 않으면 인수가 calloc(), malloc(), realloc() 또는 valloc() 함수에 의해 이전에 반환된 포인터와 일치하지 않거나, 공백이 free() 또는 realloc() 호출에 의해 할당 해제된 경우 동작은 정의되지 않는다.자유 공간을 가리키는 포인터를 사용하면 정의되지 않은 동작이 발생한다.

그것은 정의되지 않은 행동이다. 하지 마라.오직free()에서 얻은 malloc()그 전에는 절대 조정하지 마라.

는 이다.free()속도가 매우 빨라야 하므로 조정된 주소가 속한 할당을 찾으려고 하지 않고 정확히 조정된 주소에서 블록을 힙에 반환하려고 시도하십시오.그것은 정의되지 않은 행동으로 이어진다 - 대개는 부패가 쌓이거나 프로그램을 망가뜨린다.

책에서 가져온 내용:C 포인터의 이해 및 사용

메모리를 할당하면 힙 관리자가 관리하는 데이터 구조의 일부로 추가 정보가 저장된다.이 정보는 무엇보다도 블록의 크기를 포함하며, 일반적으로 할당된 블록 바로 옆에 배치된다.

참조URL: https://stackoverflow.com/questions/1957099/how-do-free-and-malloc-work-in-c

반응형