programing

어떤 상황에서 malloc이 NULL을 반환할 수 있습니까?

easyjava 2023. 9. 26. 22:38
반응형

어떤 상황에서 malloc이 NULL을 반환할 수 있습니까?

저는 그런 적이 없었고, 지금까지 몇 년 동안 프로그래밍을 해왔습니다.

에게 가 수 ?malloc실제로 작동이 안 될까요?

기억력 고갈을 말하는 아닙니다사용자가 지정한 바운드 크기의 메모리 블록을 하나만 할당하는 경우, 예를 들어 정수가 원인인 경우를 들어보겠습니다.malloc실패하다, 실패하다, 실패하다, 실패하다, 실패하다, 실패.

임베디드 시스템에서 몇가지 작업을 해야 합니다. 거기서 NULL이 자주 반환됩니다 :-

현대의 대규모 주소 공간 및 백업 저장소 시스템에서는 메모리가 부족하기가 훨씬 어렵지만, GIS나 메모리 내 데이터베이스와 같이 많은 양의 데이터를 처리하는 애플리케이션이나 버그 코드로 인해 메모리가 유출되는 곳에서는 여전히 가능합니다.

하지만 한 번도 경험하지 못했든 간에 상관이 없습니다. 표준에는 이런 일이 일어날 수 있다고 되어 있으므로 이에 응해야 합니다.저도 지난 몇 십 년간 차에 치인 적은 없지만, 그렇다고 해서 길을 건너 먼저 보지 않고 헤매는 것은 아닙니다.

편집을 다시 하십시오.

기억력 고갈을 말하는 게 아니라...

기억소진의 정의는malloc원하는 공간을 주지 않는 것.사용 가능한 모든 메모리를 할당하거나, 힙 조각화로 인해 메모리 영역의 모든 사용 가능한 블록의 합계가 더 높지만 연속된 블록을 얻을 수 없음을 의미하거나, 표준 호환 기능을 사용하여 주소 공간 사용을 인위적으로 제한하는 것과 무관합니다.

void *malloc (size_t sz) { return NULL; }

C 표준은 고장 모드를 구분하지 않고 성공 또는 실패만 합니다.

네.

를 해보세요.malloc시스템이 제공할 수 있는 것보다 더 많은 메모리(주소 공간을 모두 사용하거나 가상 메모리 - 더 작은 것 중 하나)를 저장할 수 있습니다.

malloc(SIZE_MAX)

아마 할 겁니다그렇지 않은 경우 바닥날 때까지 몇 번 반복합니다.

현재 OS에서 허용하는 것보다 더 많은 메모리를 동적으로 할당해야 하는 c로 작성된 모든 프로그램.

재미로 ubuntu를 사용하는 경우

 ulimit -v 5000

사용 가능한 메모리의 양을 어느 한 프로세스로 제한했기 때문에 실행 중인 모든 프로그램이 오류로 인해 충돌할 가능성이 높습니다.

메모리가 이미 완전히 예약되어 있거나(또는 심하게 단편화되어 있지 않은 경우), 이를 실행할 수 있는 유일한 방법은malloc()답례품을 주다NULL- 은 0은 0 입니다.

char *foo = malloc(0);

C99 표준의 §7.20.3, 제1관을 인용합니다.

요청한 공간의 크기가 0이면 동작이 fi된 구현입니다. 널 포인터가 반환되거나 반환된 포인터가 개체에 액세스하는 데 사용되지 않는 것을 제외하고는 동작이 0이 아닌 값인 것처럼 됩니다.

말로 하자면, ,malloc(0)반환할 수도 있습니다.NULL- 으로 하거나 - 0를 포인터 를 입니다합니다.

내장된 플랫폼이 더 쉽겠지만 아무 플랫폼이나 선택하세요.malloc(또는new수많은 RAM (또는 시간이 지남에 따라 RAM을 누출하거나 심지어 순진한 알고리즘을 사용하여 단편화하기도 함).잔.malloc다를(를) 반환합니다.NULL나쁜 일들이 일어날 때마다 말이죠

편집에 대한 응답입니다.네, 다시. 이 지남에 따라 시간에 따른 메모리 단편화는 한 번의 할당으로도 가능합니다를 한 합니다.int실패할 수 있습니다. 그오를 하세요.malloc지 4다에 int하지만 을 차지할 수 자체적인 부기 자료가 있으며 최소 32-64바이트를 사용하는 경우가 많습니다.

다소 표준 시스템에서 표준 1-모수 malloc을 사용하면 세 가지 고장 모드가 있습니다(생각할 수 있습니다).

  1. 요청한 할당 크기는 허용되지 않습니다.예를 들어, 일부 시스템은 더 많은 스토리지를 사용할 수 있더라도 > 16M 할당을 허용하지 않을 수 있습니다.

  2. 요청한 크기의 연속된 사용 가능 영역(기본 경계 포함)을 힙에 찾을 수 없습니다.아직도 많은 더미가 있을 수 있지만, 한 조각으로는 충분하지 않습니다.

  3. 할당된 총 힙이 "인공" 제한을 초과했습니다.예를 들어, 사용자는 200M의 여유 공간이 있고 단일 결합 힙에서 "시스템"에 사용 가능한 경우에도 1억M 이상의 할당이 금지될 수 있습니다.

(물론 2와 3의 조합을 얻을 수도 있습니다. 왜냐하면 일부 시스템은 힙이 커짐에 따라 연속하지 않은 주소 공간 블록을 할당하여 블록의 합계에 "힙 크기 제한"을 두기 때문입니다.)

일부 환경에서는 정렬 및 풀 ID와 같은 추가 malloc 매개 변수를 지원하므로 고유의 비틀림을 추가할 수 있습니다.

의 매뉴얼 페이지를 확인하기만 하면 됩니다.malloc.

성공 시 함수에 의해 할당된 메모리 블록에 대한 포인터입니다.
이 포인터의 유형은 항상 void*이며, 참조를 해제하기 위해 원하는 유형의 데이터 포인터에 캐스트할 수 있습니다.
함수가 요청한 메모리 블록을 할당하지 못한 경우 null 포인터가 반환됩니다.

예. Malloc은 커널/시스템 lib에 메모리를 할당할 수 없는 것이 확실할 때 NULL을 반환합니다.

현대 컴퓨터에서는 일반적으로 이를 볼 수 없는 이유는 Malloc이 메모리를 할당하지 않고 프로그램에 "가상 주소 공간"을 예약하여 쓰기 때문입니다.현대 리눅스와 같은 커널은 실제로 오버 커밋을 수행합니다. 즉, 시스템의 주소 공간(일반적으로 64비트 플랫폼의 경우 48비트)에 맞는 한 시스템이 실제로 제공할 수 있는 것보다 더 많은 메모리를 할당할 수 있습니다(스왑 + RAM).따라서 이러한 시스템에서는 NULL 포인터의 반환을 트리거하기 전에 OOM 킬러를 트리거할 수 있습니다.32비트 기계의 512MB RAM이 좋은 예입니다. 사용 가능한 RAM + 스왑을 몰로콜하려고 하기 때문에 OOM 킬러가 잡아먹을 C 프로그램을 작성하는 것은 사소한 일입니다.

(리눅스에서는 컴파일 시 오버커밋을 사용하지 않도록 설정할 수 있으므로, 주어진 리눅스 커널이 오버커밋을 수행할지 여부는 빌드 옵션에 따라 달라집니다.그러나 스톡 데스크톱 배포 커널이 이를 수행합니다.)

예를 들어 달라고 하셨으니, 다음과 같이 (결국) 볼 수 있는 프로그램이 있습니다.malloc돌아가다NULL:

perror();void*malloc();main(){for(;;)if(!malloc(999)){perror(0);return 0;}}

네? 고의적으로 난독화된 코드를 싫어하신다고요? ;) (몇 분간 실행되어 기계에 충돌하지 않는다면, 삭제하고 변경하십시오.999더 많은 숫자로 다시 시도합니다.)

편집: 숫자가 아무리 커도 작동하지 않으면 시스템에서 "여기 메모리가 있습니다!"라고 표시되지만 사용하려고 하지 않는 한 할당되지 않습니다.이 경우:

perror();char*p;void*malloc();main(){for(;;){p=malloc(999);if(p)*p=0;else{perror(0);return 0;}}

속임수를 써야 합니다.가 GCC 할 수 있다면, GCC다를 해서 더 수 것 char*p;void*malloc();.void*p,*malloc();하지만 정말 골프를 하고 싶으셨다면 코드 골프 SE에 나오셨을 겁니다.

malloc 매개변수가 음수이거나 0이거나 힙에 남아있는 메모리가 없는 경우.이렇게 생긴 누군가의 코드를 수정해야 했습니다.

const int8_t bufferSize = 128;
void *buffer = malloc(bufferSize);

bufferSize가 실제로 -128이므로 여기서 buffer는 NULL입니다.

언급URL : https://stackoverflow.com/questions/9101597/under-what-circumstances-can-malloc-return-null

반응형