【问题标题】:using malloc() for double pointers使用 malloc() 处理双指针
【发布时间】:2010-10-22 21:25:56
【问题描述】:

一个 malloc 问题。

首先,我生成一些字符串。

其次,我为复制指向这些字符串的指针分配了非空间。 此时程序可能会崩溃,因为我试图将这些指针复制到任何地方,但它没有崩溃。怎么可能?

任何 cmets 将不胜感激。

#include <stdio.h>

int main(int argc, char *argv[])
{
    int         i,
                iJ,
                iCharCount  = 0,
                iCharVal,
                iStrLen = 0,
                iStrNum = 50,
                iStrCount = 0,
                iAllocSize = 0;
    char       *pcStr,
               *pcStr_CurPos,
             **ppcStr,
             **ppcStr_CurPos;

    // suppose, an average length of string is * N bytes.
    iAllocSize  = iStrNum * 6;
    iStrCount = 0;

    // allocate ...
    pcStr = pcStr_CurPos = (char*) malloc (iAllocSize);

    if (pcStr==NULL){printf("NULL == malloc()\n"); exit (1);}

    for (i=0; i < iStrNum; i++)
    {
        iStrCount++;
        iStrLen = rand() % 7 + 2; // is in the range 2 to 8
            printf("Len of Str=%d; str=[", iStrLen);
        for (iJ = 0; iJ < iStrLen-1; iJ++)
        {
            // A-Z a-z
            iCharVal = rand() % 58 + 65;

            if (iCharVal >  90 && iCharVal < 97) {iJ--; continue;}

            if (pcStr_CurPos < pcStr + iAllocSize )
            {
                    printf ("%c", iCharVal);
                *pcStr_CurPos++ = iCharVal;
                iCharCount ++;
            }
            else
            {
                *pcStr_CurPos++ = 0;
                iCharCount ++;
                    printf ("]\n");
                goto exit;
            }

        }
            printf ("]\n");
        *pcStr_CurPos++ = 0;
        iCharCount ++;
    }
exit:

    // I allocate NOTHING, ...
    ppcStr = ppcStr_CurPos = (char**) malloc (0); // ZERO !

    // Copying pointers ...
    pcStr_CurPos = pcStr;
    while(pcStr_CurPos < pcStr + iCharCount)
    {
        //... BUT IT WORKS AND DON'T CRASH.
        // HOW IS IT POSSIBLE ???
        *ppcStr_CurPos++ = pcStr_CurPos;
        while (*pcStr_CurPos++) ;
    }

    ppcStr_CurPos = ppcStr;
    iStrNum = iStrCount;

    printf ("\n Output ppcStr:\n", iCharCount );

    while(iStrNum--)
    {
        printf("[%d][%s]\n", iStrNum, *(ppcStr_CurPos++));
    }

    printf ("Press Enter key or sth\n");
    getchar();
    return 0;
}

【问题讨论】:

    标签: c string pointers malloc


    【解决方案1】:

    一般来说,如果您访问未初始化的内存,C 不保证会崩溃。行为未定义,这意味着任何事情都可能发生。正如他们所说,编译器可以让恶魔飞出你的鼻子。

    【讨论】:

    • 请注意,这只有在编译器必须努力防止召唤恶魔时才有可能。
    【解决方案2】:

    我相信实际上系统分配的内存可能比您要求的多。所以这里

    ppcStr = ppcStr_CurPos = (char**) malloc (0); // ZERO !
    

    块的实际大小may be 1 or more:

    如果请求的空间大小为零,则行为是实现定义的:要么返回空指针,要么行为就好像大小是某个非零值,但返回的指针不应用于访问一个对象。

    因此,如果返回的指针不为空,它可能指向一个非零长度的缓冲区。

    那么这里

    pcStr_CurPos = pcStr;
    while(pcStr_CurPos < pcStr + iCharCount)
    {
        //... BUT IT WORKS AND DON'T CRASH.
        // HOW IS IT POSSIBLE ???
        *ppcStr_CurPos++ = pcStr_CurPos;
        while (*pcStr_CurPos++) ;
    }
    

    在将第一个字节复制到“0 字节”缓冲区后,在内部while 中,您似乎正在逐步将pcStr_CurPos 直到它指向的字符串的末尾,然后退出外部循环。因此不再复制字节!

    所以我敢说,实际上你不一定要写入未分配的内存(尽管根据上面的引用,写入该缓冲区仍然是未定义的行为 - 但正如 @novalis 正确指出的那样,未定义的行为可能不一定会导致崩溃)。

    【讨论】:

      猜你喜欢
      • 2018-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-16
      • 2016-09-29
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      相关资源
      最近更新 更多