c语言中关于指针和malloc的几个问题

2028 人浏览 | 时间: 2017-05-30 19:23:41 | 作者: codexia

此程序没有实际意义,只是我在学习中的一些困惑。除了我提到的几个疑问,不知道代码还有什么错误



#include<stdio.h>

#include<malloc.h>

void f(int * q)
{
*(q + 2) = 56;
}

int main(void)
{
int * p;

p = malloc(0);   /*1. 此时系统为其分配了0个字节(不是相当于没有分配内存吗),为什么还会返回首字节地址
                          2. 此时malloc前没有强制类型转换说明,怎么知道p指向了几个字节,也就是下面的*(p+1)和
                               *(p+2)不会报错
                       */
*p = 10;
*(p + 1) = 2;
*(p + 2) = 6;
printf("%#x\n", p);

printf("%d\n", *p);
printf("%d\n", *(p+1));//此行不是相当于系统没有为其分配内存吗,为什么还能存储数据
f(p);
printf("%d\n", *(p + 2));

return 0;
}

C++技术网会员解答:

    您好,感谢您对C++技术网的支持与信任。

    首先回答第二个问题此时malloc前没有强制类型转换说明,怎么知道p指向了几个字节,也就是下面的*(p+1)和*(p+2)不会报错。

    可以明确告诉你,下面的代码是有错误的:

int * p;
p = malloc(0);
    malloc返回的是void*指针,void*指针和int*指针是不兼容的类型,无法完成隐式的类型转换。所以你说的这个问题,和你问的就是符合的,是代码错了,不是你想错了。


    最复杂的问题就是第一个问题此时系统为其分配了0个字节(不是相当于没有分配内存吗),为什么还会返回首字节地址?

 if (!_BLOCK_TYPE_IS_VALID(nBlockUse))
{
    _RPT0(_CRT_ERROR, "Error: memory allocation: bad memory block type.\n");
}
blockSize = sizeof(_CrtMemBlockHeader) + nSize + nNoMansLandSize;

RTCCALLBACK(_RTC_FuncCheckSet_hook,(0));
pHead = (_CrtMemBlockHeader *)_heap_alloc_base(blockSize);

if (pHead == NULL)
{
    if (errno_tmp)
    {
        *errno_tmp = ENOMEM;
    }
    RTCCALLBACK(_RTC_FuncCheckSet_hook,(1));
}
else
{

    /* commit allocation */
    ++_lRequestCurr;

    if (fIgnore)
    {
        pHead->pBlockHeaderNext = NULL;
        pHead->pBlockHeaderPrev = NULL;
        pHead->szFileName = NULL;
        pHead->nLine = IGNORE_LINE;
        pHead->nDataSize = nSize;
        pHead->nBlockUse = _IGNORE_BLOCK;
        pHead->lRequest = IGNORE_REQ;
    }
    else {
        /* keep track of total amount of memory allocated */
        if (SIZE_MAX - _lTotalAlloc > nSize)
        {
            _lTotalAlloc += nSize;
        }
        else
        {
            _lTotalAlloc = SIZE_MAX;
        }
        _lCurAlloc += nSize;

        if (_lCurAlloc > _lMaxAlloc)
        _lMaxAlloc = _lCurAlloc;

        if (_pFirstBlock)
            _pFirstBlock->pBlockHeaderPrev = pHead;
        else
            _pLastBlock = pHead;

        pHead->pBlockHeaderNext = _pFirstBlock;
        pHead->pBlockHeaderPrev = NULL;
        pHead->szFileName = (char *)szFileName;
        pHead->nLine = nLine;
        pHead->nDataSize = nSize;
        pHead->nBlockUse = nBlockUse;
        pHead->lRequest = lRequest;

        /* link blocks together */
        _pFirstBlock = pHead;
    }

    /* fill in gap before and after real block */
    memset((void *)pHead->gap, _bNoMansLandFill, nNoMansLandSize);
    memset((void *)(pbData(pHead) + nSize), _bNoMansLandFill, nNoMansLandSize);

    /* fill data with silly value (but non-zero) */
    memset((void *)pbData(pHead), _bCleanLandFill, nSize);

    RTCCALLBACK(_RTC_FuncCheckSet_hook,(1));

    retval=(void *)pbData(pHead);
请微信扫码阅读
为防止恶意爬虫,
已开启反爬机制

相关阅读