一个动态内存分配的有关问题,帮看看

一个动态内存分配的问题,帮看看。
#include <stdio.h>
#include<stdlib.h>
int main()
{

char *pt;
if((pt = (char*)malloc(0)) == NULL)
printf("未分配好地址");
else
printf("已经分配好地址");
return 0;
}
输出结果是“已经分配好地址”
为什么是这个?

------解决方案--------------------
记得某本书上就写过“居然能申请大小为0的空间,大多数人都不知道这一点”

------解决方案--------------------
因为如下:
先看Linux下的:
malloc() allocates size bytes and returns a pointer to the allocated memory. The memory is not cleared. If
size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed
to free().
在看MSDN的解释:
malloc returns a void pointer to the allocated space or NULL if there is insufficient memory available. To return a pointer to a type other than void, use a type cast on the return value. The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item. Always check the return from malloc, even if the amount of memory requested is small.


------解决方案--------------------
这是我在linux下通过man工具查看的malloc的函数介绍:
功能描述:
malloc() allocates size bytes and returns a pointer to the allocated memory. The memory is not cleared. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
返回值描述:
malloc(), return a pointer to the allocated memory, which is suitably aligned for any kind of variable. On error, these functions return NULL. NULL may also be returned by a successful call to malloc() with a size of zero, or by a successful call to calloc() with nmemb or size equal to zero.
因此,malloc如果申请的空间为零时,也有可能会返回NULL。
------解决方案--------------------
记得某本书上就写过“居然能申请大小为0的空间,大多数人都不知道这一点”

------解决方案--------------------
C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\malloc.c
C/C++ code
/***
*malloc.c - Get a block of memory from the heap
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       Defines the malloc() function.
*
*******************************************************************************/

#include <cruntime.h>
#include <malloc.h>
#include <internal.h>
#include <mtdll.h>
#include <dbgint.h>
#include <rterr.h>

#include <windows.h>
#include <winheap.h>
#include <rtcsup.h>

extern int _newmode;    /* malloc new() handler mode */

#ifdef _DEBUG
#define _heap_alloc _heap_alloc_base
#endif  /* _DEBUG */

/***
*void *_heap_alloc_base(size_t size) - does actual allocation
*
*Purpose:
*       Same as malloc() except the new handler is not called.
*
*Entry:
*       See malloc
*
*Exit:
*       See malloc
*
*Exceptions:
*
*******************************************************************************/

__forceinline void * __cdecl _heap_alloc (size_t size)

{

    if (_crtheap == 0) {
        _FF_MSGBANNER();    /* write run-time error banner */
        _NMSG_WRITE(_RT_CRT_NOTINIT);  /* write message */
        __crtExitProcess(255);  /* normally _exit(255) */
    }

    return HeapAlloc(_crtheap, 0, size ? size : 1);
}


/***
*void *malloc(size_t size) - Get a block of memory from the heap
*
*Purpose:
*       Allocate of block of memory of at least size bytes from the heap and
*       return a pointer to it.
*
*       Calls the new appropriate new handler (if installed).
*
*Entry:
*       size_t size - size of block requested
*
*Exit:
*       Success:  Pointer to memory block
*       Failure:  NULL (or some error value)
*
*Uses:
*
*Exceptions:
*
*******************************************************************************/

void * __cdecl _malloc_base (size_t size)
{
    void *res = NULL;

    //  validate size
    if (size <= _HEAP_MAXREQ) {
        for (;;) {

            //  allocate memory block
            res = _heap_alloc(size);

            //  if successful allocation, return pointer to memory
            //  if new handling turned off altogether, return NULL

            if (res != NULL)
            {
                break;
            }
            if (_newmode == 0)
            {
                errno = ENOMEM;
                break;
            }

            //  call installed new handler
            if (!_callnewh(size))
                break;

            //  new handler was successful -- try to allocate again
        }
    } else {
        _callnewh(size);
        errno = ENOMEM;
        return NULL;
    }

    RTCCALLBACK(_RTC_Allocate_hook, (res, size, 0));
    if (res == NULL)
    {
        errno = ENOMEM;
    }
    return res;
}