더 작은 크기로 재할당을 호출하면 나머지가 해방된다고 가정할 수 있습니까?
다음 코드의 매우 짧은 단편을 고려해 보겠습니다.
#include <stdlib.h>
int main()
{
char* a = malloc(20000);
char* b = realloc(a, 5);
free(b);
return 0;
}
재할당을 위한 man 페이지를 읽은 후, 저는 두 번째 줄이 19995 추가 바이트를 해방시킬지 완전히 확신하지 못했습니다.하기: man 페인기하용지이기▁to.The realloc() function changes the size of the memory block pointed to by ptr to size bytes.
하지만 그 정의로 볼 때, 나머지 사람들이 풀려날 것이라고 확신할 수 있을까요?
내 말은, 그 블록이 가리키는 곳은b
확실히 5개의 자유 바이트를 포함하고 있는데, 게으른 준수 할당자가 재할당 라인에 대해 아무것도 하지 않는 것으로 충분할까요?
제가 " ": 고참사년는할당자는하 1995"를 할 때 추가 롭게 하는 것 .free(b)
: 선:
==4457== HEAP SUMMARY:
==4457== in use at exit: 5 bytes in 1 blocks
==4457== total heap usage: 2 allocs, 1 frees, 20,005 bytes allocated
예, 새로운 객체를 할당할 수 있다면 C 표준에 의해 보장됩니다.
(C99, 7.20.3.4p2) "realloc 함수는 ptr이 가리키는 오래된 객체의 할당을 해제하고 크기로 지정된 크기를 가진 새로운 객체에 포인터를 반환합니다."
예, 성공한 경우.
코드 조각에는 잘 알려진 악성 버그가 표시됩니다.
char* b = (char*) realloc(a, 5);
성공하면 에 이작성이할메에 a
자유로워질 것이고,b
는 원래 블록과 겹치거나 겹치지 않을 수 있는 5바이트의 메모리를 가리킵니다.
하지만, 통화가 실패하면,b
될 것입니다.null
,그렇지만a
원래 메모리를 가리키며 이 메모리는 여전히 유효합니다.그런 경우에는, 당신은 할 필요합니다.free(a)
메모리를 해제할 수 있습니다.
일반적인 (위험한) 관용구를 사용하면 더 나빠집니다.
a = realloc(a, NEW_SIZE); // Don't do this!
으로 가 온 realloc
는 패실, 니다것입이 됩니다.null
원래 메모리가 분리되어 프로그램이 종료될 때까지 복구할 수 없게 됩니다.
이는 libc 구현에 따라 다릅니다.다음은 모두 준수 동작입니다.
- 아무것도 하지 않음, 즉 데이터를 그대로 유지하고 이전 블록을 반환함, 현재 사용되지 않는 바이트를 추가 할당에 재사용할 수 있음(
패이크 재사용은일반적이지않음) - 데이터를 새 블록에 복사하고 이전 블록을 OS에 다시 릴리스하기
- 새 블록에 데이터 복사 및 추가 할당을 위해 이전 블록 유지
또한 가능합니다.
- 새 블록을 할당할 수 없는 경우 null 포인터 반환
이 경우 이전 데이터도 그대로 남아 메모리 누수가 발생할 수 있습니다. 예를 들어, 반환 값이 다음과 같습니다.realloc()
해당 블록에 대한 포인터의 유일한 복사본을 덮어씁니다.
합리적인 libc 구현은 휴리스틱을 사용하여 어떤 솔루션이 가장 효율적인지 결정합니다.
또한 이 설명은 구현 수준입니다.의미론적으로,realloc()
할당이 실패하지 않는 한 항상 개체를 해제합니다.
19995바이트가 해제되었을 가능성은 거의 없어 보입니다.더 가능성이 높은 것은 재할당이 20000바이트 블록을 다른 5바이트 블록으로 대체했다는 것입니다. 즉, 20000바이트 블록이 해제되고 새로운 5바이트 블록이 할당되었다는 것입니다.
재할당 함수의 계약은 다음과 같습니다.
void* 결과 = 재할당(ptr, new_size)
- 결과가 NULL이면 ptr은 여전히 유효하며 변경되지 않습니다.
- 결과가 NULL이 아닌 경우 ptr은 이제 유효하지 않으므로(해제된 것처럼) 다시 사용해서는 안 됩니다.result는 이제 정확히 new_size 바이트의 데이터에 대한 포인터입니다.
후드 아래에서 진행되는 작업에 대한 정확한 세부 사항은 구현에 따라 다릅니다. 예를 들어 결과는 ptr과 같을 수 있으며(그러나 new_size를 초과하는 추가 공간은 더 이상 터치해서는 안 됩니다) 재할당은 무료를 호출하거나 자체 내부 자유 표현을 수행할 수 있습니다.중요한 것은 개발자로서 당신은 ptrif realloc가 null이 아닌 것을 반환할 경우 더 이상 책임을 지지 않으며, realloc가 NULL을 반환할 경우에도 여전히 책임을 져야 한다는 것입니다.
언급URL : https://stackoverflow.com/questions/9575122/can-i-assume-that-calling-realloc-with-a-smaller-size-will-free-the-remainder
'programing' 카테고리의 다른 글
동일한 ID에 대한 제한이 있는 선택 (0) | 2023.08.05 |
---|---|
최대 절전 모드:역직렬화할 수 없음 - 잘못된 스트림 헤더 (0) | 2023.08.05 |
도커: 상위 디렉토리에서 파일 추가 (0) | 2023.08.05 |
메인 스레드에서 메서드를 호출하시겠습니까? (0) | 2023.08.05 |
Swift UI 해제 모달 (0) | 2023.08.05 |