답변:
사양에 따르면 malloc (0) 은 "널 포인터 또는 free ()에 성공적으로 전달할 수있는 고유 포인터"를 반환합니다.
이렇게하면 기본적으로 아무것도 할당 할 수 없지만 걱정없이 "artist"변수를 free () 호출에 전달할 수 있습니다. 실용적인 목적을 위해 다음을 수행하는 것과 거의 동일합니다.
artist = NULL;
C 표준 (C17 7.22.3 / 1)은 다음과 같이 말합니다.
요청 된 공간의 크기가 0이면 동작은 정의 된 구현입니다. null 포인터가 반환되거나 반환 된 포인터가 개체에 액세스하는 데 사용되지 않는 것을 제외하고는 크기가 0이 아닌 값인 것처럼 동작합니다.
따라서 역 참조되지 않을 수 있는 유효한 포인터 또는 malloc(0)
반환 할 수 있습니다 . 두 경우 모두 전화하는 것이 완벽하게 유효합니다.NULL
free()
하는 것이 합니다.
예를 들어 루프에서 호출되는 malloc(0)
경우를 제외하고는 실제로 많이 사용 되지 않는다고 생각합니다.malloc(n)
n
0 일 수 합니다.
링크의 코드를 보면 저자가 두 가지 오해를 가지고 있다고 생각합니다.
malloc(0)
항상 유효한 포인터를 반환 하고free(0)
나쁘다.그래서 그는 artist
다른 변수들에 항상 "유효한"값이 있는지 확인 했습니다. 댓글은 다음과 같이 말합니다 // these must always point at malloc'd data
.
malloc(0)
유효한 포인터를 반환하고 malloc()
반환 NULL
항상 "실패"를 의미하고, 0
일관성있는, 더 이상 특별한 경우가 아니다.
malloc
메모리를 얻지 못하는 상황 은 구현에 따라 정의되므로 구현에서는 크기 0 할당이 항상 만족스럽지 ENOMEM
않으며 ( ), 이제 malloc(0)
0 (와 함께 errno==ENOMEM
)을 반환하는 것이 일관성이 있다고 정의 할 수 있습니다. :-)
realloc
의해 반환 된 포인터 수 있습니까 malloc(0)
? 당신은 할 수 realloc((char*)NULL)
있습니까?
malloc (0) 동작은 구현에 따라 다릅니다. 라이브러리는 NULL을 반환하거나 메모리가 할당되지 않은 일반 malloc 동작을 가질 수 있습니다. 무엇을하든 어딘가에 문서화해야합니다.
일반적으로 유효하고 고유하지만 역 참조해서는 안되는 포인터를 반환합니다. 또한 실제로 아무것도 할당하지 않았더라도 메모리를 소비 할 수 있습니다.
널이 아닌 malloc (0) 포인터를 재 할당 할 수 있습니다.
하지만 malloc (0)을 그대로 사용하는 것은별로 유용하지 않습니다. 동적 할당이 0 바이트이고 유효성을 검사 할 필요가 없을 때 주로 사용됩니다.
malloc()
"하우스 키핑 정보"를 어딘가에 보관해야합니다 (예 : 할당 된 블록의이 크기 및 기타 보조 데이터). 따라서를 반환 malloc(0)
하지 않으면 NULL
해당 정보를 저장하는 데 메모리를 사용하고, 그렇지 않으면 free()
메모리 누수를 구성합니다.
malloc()
이 반환 하지 않는 고유 한 포인터를 반환하거나 NULL
.
malloc(0)
. 그러나 표준 C 라이브러리의 동일한 구현에서 NULL을 realloc(ptr, 0)
해제 ptr
하고 반환합니다.
이 페이지의 다른 곳에서 "malloc (0)은 유효한 메모리 주소를 반환하고 범위는 메모리가 할당되는 포인터의 유형에 따라 달라집니다"로 시작하는 답변이 있습니다. 이 진술은 정확하지 않습니다 (저는 그 대답에 대해 직접 언급 할만한 평판이 충분하지 않으므로이 주석을 바로 아래에 둘 수 없습니다).
malloc (0)을 수행하면 올바른 크기의 메모리가 자동으로 할당 되지 않습니다 . malloc 함수는 결과를 캐스팅하는 대상을 인식하지 못합니다. malloc 함수는 인수로 제공하는 크기 번호에만 의존합니다. 예를 들어 0이 아닌 int를 저장하기에 충분한 저장 공간을 확보하려면 malloc (sizeof (int))을 수행해야합니다.
malloc(0)
코드가 구현에 특정한 동작에 의존하지 않는 한 나에게 의미가 없습니다. 코드가 이식 가능하도록 의도 된 경우 NULL 반환 malloc(0)
이 실패가 아니라는 사실을 고려해야합니다 . 그렇다면 artist
유효한 성공적인 결과이고 코드가 적고 유지 보수 프로그래머가 시간을 들여 알아내는 데 시간이 걸리지 않기 때문에 어쨌든 NULL을 할당하지 않는 이유 는 무엇입니까?
malloc(SOME_CONSTANT_THAT_MIGHT_BE_ZERO)
또는 malloc(some_variable_which_might_be_zero)
값이 0이면 NULL 반환을 실패로 처리하지 않도록 특별히주의해야하지만, 크기가 0이면 괜찮습니다.
여기에는 절반 정도의 정답이 있으므로 여기에 어려운 사실이 있습니다. 의 맨 페이지 malloc()
내용 :
크기가 0이면 malloc ()은 NULL 또는 나중에 free ()에 성공적으로 전달할 수있는 고유 한 포인터 값을 반환합니다.
즉,의 결과 malloc(0)
가 고유하거나 NULL이 아니라는 보장이 전혀 없습니다 . 유일한 보증은의 정의에 의해 제공됩니다 free()
. 맨 페이지에 다음과 같은 내용이 있습니다.
ptr이 NULL이면 작업이 수행되지 않습니다.
따라서 malloc(0)
반환되는 것이 무엇이든 안전하게 전달할 수 free()
있습니다. 그러나 NULL
포인터도 마찬가지 입니다.
결과적으로 글쓰기 artist = malloc(0);
는 글쓰기보다 낫지 않습니다. artist = NULL;
malloc(0)
반환 말, 0x1로, 그리고 수 free()
는 0x0으로 위해가 마찬가지로 0x1로의 특별한 경우의 체크를 가질 수있다.
NULL
또는 고유 포인터" 여야 함을 지정하지 않습니다 . 대신 '널 포인터 또는 할당 된 공간에 대한 포인터'. 고유 한 요구 사항 이 없습니다 . OTOH, 고유하지 않은 특수 값을 반환하면 고유 값을 계산하는 코드가 중단 될 수 있습니다. SO에 대한 코너 케이스 질문 일 수 있습니다.
man
* nix에서 사용되는 구현 정의 형식을 문서화 할 수도 있습니다. 이 경우에는 그렇지 않습니다,하지만 여전히 일반 C.에 대한 정식 소스 아니다
이걸하면 안되는 이유 ...
malloc의 반환 값은 구현에 따라 다르므로 NULL 포인터 또는 다른 주소를 다시 얻을 수 있습니다. 오류 처리 코드가 크기와 반환 값을 모두 확인하지 않으면 결국 힙 버퍼 오버플로가 발생하여 안정성 문제 (충돌) 또는 더 나쁜 보안 문제가 발생할 수 있습니다.
반환 된 주소를 통해 추가로 메모리에 액세스하면 크기가 0이고 구현이 NULL이 아닌 값을 반환하는 경우 힙이 손상되는이 예를 고려하십시오.
size_t size;
/* Initialize size, possibly by user-controlled input */
int *list = (int *)malloc(size);
if (list == NULL) {
/* Handle allocation error */
}
else {
/* Continue processing list */
}
추가 읽기를 위해 위의 예제를 사용한 CERT 코딩 표준 의이 보안 코딩 페이지 를 참조하십시오 .
사실, 나는 이것을 본 적이 없다. 이것은 내가이 구문을 본 것은 처음이다. 함수 과잉의 고전적인 경우라고 말할 수있다. Reed의 대답과 관련하여 과부하 된 함수처럼 보이는 비슷한 것이 있음을 지적하고 싶습니다 realloc
.
realloc(foo, size);
입니다. NULL이 아닌 포인터와 크기 0을 realloc에 전달하면 realloc은 마치 free (…)를 호출 한 것처럼 동작합니다.realloc(foo, size);
. NULL 포인터를 전달하고 크기가 0이 아닌 경우 realloc은 malloc (…)을 호출 한 것처럼 작동합니다.이것이 도움이되기를 바랍니다. 안부, Tom.
malloc (0)은 NULL을 반환하거나 올바른 포인터를 해제 할 수 있습니다. 그리고 그것이 가리키는 메모리가 쓸모 없거나 쓰거나 읽을 수없는 것처럼 보이지만 항상 사실은 아닙니다. :)
int *i = malloc(0);
*i = 100;
printf("%d", *i);
여기서 세분화 오류를 예상하지만 놀랍게도 이것은 100을 인쇄합니다! malloc이 처음으로 malloc을 호출 할 때 실제로 많은 양의 메모리를 요청하기 때문입니다. 이후 malloc에 대한 모든 호출은 그 큰 덩어리의 메모리를 사용합니다. 그 거대한 덩어리가 끝난 후에야 새로운 메모리가 요구됩니다.
malloc (0) 사용 : 후속 malloc 호출이 더 빨라지기를 원하는 상황에있는 경우 malloc (0)을 호출해야합니다 (가장자리 경우 제외).
*i
귀하의 경우에 쓰기가 중단되지 않을 수도 있지만 그럼에도 불구하고 정의되지 않은 동작입니다. 비강 악마를 조심하세요!
malloc(0)
언급되지 않은 용도 가 있습니다. 특히 DEBUG 빌드에서 NULL이 아닌 값을 반환하는 구현에서는 요청한 것보다 더 많이 할당하고 내부 헤더를 지나칠 수있는 포인터를 제공합니다. 이를 통해 일련의 할당 전후에 이것을 얻을 경우 실제 메모리 사용량에 대한 느낌 을 얻을 수 있습니다 . 예 : void* before = malloc(0); ... void* after = malloc(0); long long total = after - before;
또는 일부.
malloc(0)
. 어떤 장을 참조하고 있는지 말씀해 주시겠습니까? 정확한 견적을 제공하는 것도 좋을 것입니다.
일부 무작위 malloc 소스 에 따르면 확실하지 않습니다.내가 찾은 코드 0을 입력하면 NULL이 반환됩니다. 따라서 아티스트 포인터를 NULL로 설정하는 미친 방법입니다.
http://www.raspberryginger.com/jbailey/minix/html/lib_2ansi_2malloc_8c-source.html
다음은 valgrind 메모리 검사 도구로 실행 한 후의 분석입니다.
==16740== Command: ./malloc0
==16740==
p1 = 0x5204040
==16740==
==16740== HEAP SUMMARY:
==16740== in use at exit: 0 bytes in 0 blocks
==16740== total heap usage: 2 allocs, 2 frees, 1,024 bytes allocated
==16740==
==16740== All heap blocks were freed -- no leaks are possible
내 샘플 코드는 다음과 같습니다.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
//int i;
char *p1;
p1 = (char *)malloc(0);
printf("p1 = %p\n", p1);
free(p1);
return 0;
}
기본적으로 1024 바이트가 할당됩니다. malloc의 크기를 늘리면 할당 된 바이트가 1025만큼 늘어납니다.
Reed Copsey 답변과 malloc man 페이지에 따르면 테스트 할 몇 가지 예제를 작성했습니다. 그리고 malloc (0)이 항상 고유 한 값을 제공한다는 것을 알았습니다. 내 예를 참조하십시오.
char *ptr;
if( (ptr = (char *) malloc(0)) == NULL )
puts("Got a null pointer");
else
puts("Got a valid pointer");
출력은 "Got a valid pointer"이며 이는 ptr
null이 아님 을 의미 합니다.
malloc(0)
유효한 메모리 주소를 반환하고 범위는 메모리가 할당되는 포인터 유형에 따라 달라집니다. 또한 메모리 영역에 값을 할당 할 수 있지만 사용되는 포인터 유형에 따라 범위 내에 있어야합니다. 할당 된 메모리를 해제 할 수도 있습니다. 예를 들어 설명하겠습니다.
int *p=NULL;
p=(int *)malloc(0);
free(p);
위의 코드는 gcc
Linux 시스템 의 컴파일러에서 잘 작동합니다 . 32 비트 컴파일러가있는 경우 정수 범위 (예 : -2147483648 ~ 2147483647)의 값을 제공 할 수 있습니다. 문자에도 동일하게 적용됩니다. 선언 된 포인터의 유형이 변경되면 malloc
typecast에 관계없이 값의 범위가 변경됩니다.
unsigned char *p=NULL;
p =(char *)malloc(0);
free(p);
p
unsigned int로 선언되었으므로 0에서 255까지의 char 값을 사용합니다.
malloc()
캐스트에 대해 아무것도 알지 못합니다 (실제로 C에서 완전히 능숙 함). 의 반환 값을 역 참조하면 malloc(0)
정의되지 않은 동작이 호출됩니다.
여기에서 잘못된 인상을 수정하려면 :
artist = (char *) malloc(0);
결코 돌아 오지 않을 것입니다 NULL
; 그것은 artist = NULL;
. 간단한 프로그램을 작성하고 비교 artist
와 함께 NULL
. if (artist == NULL)
거짓이고 if (artist)
참입니다.