programing

malloc (0)은 무엇을 반환합니까?

copyandpastes 2021. 1. 18. 22:16
반응형

malloc (0)은 무엇을 반환합니까?


이 질문에 이미 답변이 있습니다.

malloc(0)반환은 무엇입니까 ? 대답이 동일 realloc(malloc(0),0)할까요?

#include<stdio.h>
#include<malloc.h>
int main()
{
        printf("%p\n", malloc(0));
        printf("%p\n", realloc(malloc(0), 0));
        return 0;
}

Linux gcc의 출력 :

manav@manav-workstation:~$ gcc -Wall mal.c
manav@manav-workstation:~$ ./a.out
0x9363008
(nil)
manav@manav-workstation:~$

출력은 malloc(0). 이것이 일반적인 대답입니까? 그리고 왜 누군가가 학술 연구 외에 그러한 포인터를 얻는 데 관심이 있습니까?

편집하다:

malloc(0)더미 포인터를 반환 하면 다음은 어떻게 작동합니까?

int main()
{
    void *ptr = malloc(0);
    printf("%p\n", realloc(ptr, 1024));
    return 0;
}

편집하다:

다음 코드는 모든 반복에 대해 "가능"을 출력합니다. 왜 실패하지 않아야합니까?

#include<stdio.h>
#include<malloc.h>
int main()
{

        int i;
        void *ptr;
        printf("Testing using BRUTE FORCE\n");
        for (i=0; i<65000; i++)
        {
                ptr = malloc(0);
                if (ptr == realloc(ptr, 1024))
                        printf("Iteration %d: possible\n", i);
                else
                {
                        printf("Failed for iteration %d\n", i);
                        break;
                }
        }
        return 0;
}

다른 사람들은 어떻게 malloc(0)작동 하는지 대답했습니다 . 아직 답변되지 않은 질문 중 하나에 대답하겠습니다. 질문은 다음에 관한 것입니다 realloc(malloc(0), 0).

무엇을 malloc(0)반환합니까? 대답이 동일 realloc(malloc(0),0)할까요?

표준은 다음과 같이 말합니다 realloc(ptr, size).

  • 경우 ptr이며 NULL, 그것은처럼 작동 malloc(size),
  • 그렇지 않으면 ( ptris not NULL), by에 대한 이전 개체 포인터를 할당 해제하고 ptr새로 할당 된 버퍼에 대한 포인터를 반환합니다. 그러나 size0이면 C89는 효과가 free(ptr). 흥미롭게도 C99 초안 (n1256 또는 n1336)에서 해당 진술을 찾을 수 없습니다. C89에서이 경우 반환 할 수있는 유일한 값은 NULL.

따라서 두 가지 경우가 있습니다.

  • malloc(0)NULL구현에 반환 됩니다. 그러면 귀하의 realloc()전화는 realloc(NULL, 0). malloc(0)위와 동일합니다 ( NULL이 경우).
  • malloc(0)비를 반환합니다 NULL. 그런 다음 호출은 free(malloc(0)). 이 경우, malloc(0)realloc(malloc(0), 0)있습니다 없습니다 해당.

여기에 흥미로운 경우가 있습니다. 두 번째 경우, 성공하지 malloc(0)않은 경우 반환 되면 NULL여전히 NULL실패를 나타 내기 위해 반환 될 수 있습니다 . :이 같은 호출됩니다 realloc(NULL, 0)에 해당하는 것, malloc(0)또는 반환하지 않을 수있다, NULL.

C99의 누락이 감독인지 또는 C99에서 realloc(ptr, 0)NULL ptr와 동일하지 않음 의미하는지 확실 하지 않습니다 free(ptr). 나는 방금 이것을 시도했고 gcc -std=c99위의 내용은 free(ptr).

편집 : 나는 당신의 혼란이 무엇인지 이해한다고 생각합니다.

예제 코드의 스 니펫을 살펴 보겠습니다.

ptr = malloc(0);
if (ptr == realloc(ptr, 1024))

위의 내용은 malloc(0) == realloc(malloc(0), 1024). 두 번째에서는 malloc()호출이 두 번 수행되는 반면 첫 번째에서는 이전에 할당 된 포인터를에 전달합니다 realloc().

먼저 첫 번째 코드를 분석해 보겠습니다. 성공으로 malloc(0)돌아 오지 않는다고 가정하면 유효한 값이 있습니다. 당신이 할 때 , 기본적으로 당신에게 크기 1024가 새로운 버퍼를 제공하고,이 무효가됩니다. 준수 구현은 이미에있는 주소와 동일한 주소를 반환 할 수 있습니다 . 따라서 귀하의 상태가 참으로 반환 될 수 있습니다. (그러나 after 값을 보는 것은 정의되지 않은 동작 일 수 있습니다.)NULLptrrealloc(ptr, 1024)realloc()ptrptrifptrrealloc(ptr, 1024)

Now the question you ask: malloc(0) == realloc(malloc(0), 1024). In this case, let's assume that both the malloc(0) on the LHS and RHS returns non-NULL. Then, they are guaranteed to be different. Also, the return value from malloc() on the LHS hasn't been free()d yet, so any other malloc(), calloc(), or realloc() may not return that value. This means that if you wrote your condition as:

if (malloc(0) == realloc(malloc(0), 1024)
    puts("possible");

you won't see possible on the output (unless both malloc() and realloc() fail and return NULL).

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    void *p1;
    void *p2;

    p1 = malloc(0);
    p2 = realloc(p1, 1024);
    if (p1 == p2)
        puts("possible, OK");

    /* Ignore the memory leaks */
    if (malloc(0) == realloc(malloc(0), 1024))
        puts("shouldn't happen, something is wrong");
    return 0;
}

On OS X, my code didn't output anything when I ran it. On Linux, it prints possible, OK.


malloc(0) is Implementation Defined as far as C99 is concerned.

From C99 [Section 7.20.3]

The order and contiguity of storage allocated by successive calls to the calloc, malloc, and realloc functions is unspecified. The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly deallocated). The lifetime of an allocated object extends from the allocation until the deallocation. Each such allocation shall yield a pointer to an object disjoint from any other object. The pointer returned points to the start (lowest byte address) of the allocated space. If the space cannot be allocated, a null pointer is returned. If the size of the space requested is zero, the behavior is implementation- defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.


In C89, malloc(0) is implementation dependent - I don't know if C99 has fixed this or not. In C++, using:

char * p = new char[0];

is well defined - you get a valid, non-null pointer. Of course, you can't use the pointer to access what it points to without invoking undefined behaviour.

As to why this exists, it is convenient for some algorithms, and means you don't need to litter your code with tests for zero values.


C99 standard

If the space cannot be allocated, a nullpointer is returned. If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.


The comp.lang.c FAQ has the following to say:

The ANSI/ISO Standard says that it may do either; the behavior is implementation-defined (see question 11.33). Portable code must either take care not to call malloc(0), or be prepared for the possibility of a null return.

So, it's probably best to avoid using malloc(0).


See C99, section 7.20.3:

If the size of the space requested is zero, the behavior is implementationdefined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.

This is valid for all three allocation functions (ie calloc(), malloc() and realloc()).


One point nobody cared to talk about yet, in your first program is that realloc with length 0 is the same thing as free.

from the Solaris man page:

The realloc() function changes the size of the block pointed to by ptr to size bytes and returns a pointer to the (possibly moved) block. The contents will be unchanged up to the lesser of the new and old sizes. If ptr is NULL, realloc() behaves like malloc() for the specified size. If size is 0 and ptr is not a null pointer, the space pointed to is made available for further allocation by the application, though not returned to the system. Memory is returned to the system only upon termination of the application.

If one doesn't know that it can be a source of bad surprise (happened to me).


I think it depends. I checked the Visual Studio 2005 sources and saw this in the _heap_alloc function:

if (size == 0)
    size = 1;

I think that in many cases you may want a valid pointer, even when asking for zero bytes. This is because this consistent behavior makes it easier to check your pointers because: if you have a non-NULL pointer it's OK; if you have a NULL pointer you probably have a problem. That's why I think that most implementations will return a valid pointer, even when asking for zero bytes.


If malloc(0) returns dummy pointer, then how does following works:

void *ptr = malloc(0);

printf("%p\n", realloc(ptr, 1024));

I don't know what you mean by "dummy pointer". If malloc(0) returns non-NULL, then ptr is a valid pointer to a memory block of size zero. The malloc implementation saves this information in an implementation-specific way. realloc knows the (implementation-specific) way to figure out that ptr points to a memory block of size zero.

(How malloc/realloc/free do this is implementation-specific. One possibility is to allocate 4 bytes more than requested and store the size just before the memory block. In that case, ((int *)ptr)[-1] would give the memory block size, which is 0. You should never do this from your code, it's only for use by realloc and free).

ReferenceURL : https://stackoverflow.com/questions/2132273/what-does-malloc0-return

반응형