2010-10-22 108 views
2

malloc問題。malloc()用於雙指針

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

第二,我分配無空間來複制指向這些字符串的指針。 在這個時候程序應該可能崩潰,因爲我試圖將這些指針複製到任何地方,但它不會崩潰。這怎麼可能?

任何意見,將不勝感激。

#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; 
} 

回答

9

一般來說,如果您訪問未初始化的內存,C不保證會崩潰。行爲是不確定的,這意味着任何事情都可能發生。正如他們所說,編譯器可以讓惡魔從你的鼻子裏飛出來。

+1

請注意,這隻有在編譯器必須盡力防止召喚惡魔時纔有可能。 – 2010-10-22 22:02:41

1

我相信在實踐中,系統可能會分配比您要求的更多的內存。所以在這裏

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++) ; 
} 

第1字節複製到「0字節」緩衝器,內部while後,你似乎通過,直到字符串的結尾它指向,則因此退出踩着pcStr_CurPos從外部循環。因此沒有更多的字節被複制!

所以我敢說,在實踐中,你不一定會寫入未分配的內存(儘管根據上面的報價,它仍然是未定義的行爲寫入該緩衝區 - 但正如@novalis指出的,未定義的行爲可能不一定會導致崩潰)。