1. 程式人生 > >那些年,踩過的坑

那些年,踩過的坑

 1. fread函式需要注意的點

bool ip_arrival(string ip) {
    FILE *pfd = NULL;
    unsigned char tmpbuf[1024];
    //memset(tmpbuf, '\0', sizeof(tmpbuf));
    //Block ping
    int maxnaps = 10;
    int fread_num = 0;
    while (maxnaps-- > 0) {

        string cmd = string("ping -c1 ") + ip;
        pfd = popen(cmd.c_str(), "r");
        if (pfd == NULL) {
            WFD_SINK_LOG(" popen failed\n");
            return false;
        }

        if( (fread_num = fread(tmpbuf, 1, sizeof(tmpbuf), pfd)) <= 0) {
            pclose(pfd);
            return false;
        }
        WFD_SINK_LOG("\ntmpbuf: %s\n", tmpbuf);
        if(strstr((const char *)&tmpbuf, "bytes from") ) {
            pclose(pfd);
            return true;
        }
        pclose(pfd);
        WFD_SINK_LOG("maxnaps: %d\n", maxnaps);
    }
    WFD_SINK_LOG("the ip: %s  can not arrive\n", ip.c_str());
    return false;
}

從上面的程式碼可以看出fread有可能出問題,因為tmpbuf沒有'\0'結尾,

需要補上,tmpbuf[fread_num] = '\0'; 這個!

在釋放記憶體後,要將相關指標置為NULL. 這樣可以防止後續對該指標進行操作時出錯, 先看一個不好的風格.該程式風格不好(儘管正確):

  1. #include<stdio.h>
  2. int main()  
  3. {  
  4.     int *p = newint(5);  
  5.     delete p;  
  6.     return 0;  
  7. }  

現在假設程式很大,不小心又釋放了一次,即:

  1. #include<stdio.h>
  2. int main()  
  3. {  
  4.     int *p = newint(5);  
  5.     delete p;  
  6.     delete p;  
  7.     return 0;  
  8. }  

     執行程式,程式會crash, 這就是記憶體過度釋放的後果, 如果程式很大,就很不好找. 而且,編譯器提示的資訊也非常有限。來看看下面的程式,在釋放後將指標置為NULL:

  1. #include<stdio.h>
  2. int main()  
  3. {  
  4.     int *p = newint(5);  
  5.     delete p;  
  6.     p = NULL; // 如果沒有這一個語句,程式就會crash
  7.     delete p; // 沒關係, 但通常會對是否為NULL進行判斷, 這樣就更需要將p置為NULL了
  8.     p = NULL;
  9.     return 0;  
  10. }  

   結果程式可以正常執行,這就是將p置為NULL的好處。

            事實上,在下面的程式可以看出問題:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char *p = NULL;
    p = (char * )malloc( 4 * sizeof( char ) );
    free(p);
    strcpy( p, "abc" );
    printf( "%s\n", p );
    return 0;
} 
可以正常列印,這裡就出現了大家常見的“懸空指標”,

下面的例子也是:

void *p;
p=malloc(10);//......
free(p);

正確的做法是:需要將p = null,不然出錯誤!這樣的錯誤經常出現!

第三:呼叫fclose之後,FILE *fp會變成NULL嗎?不會,沒有什麼機制把fp置空的動作,只是這個時候fp所指向的區域已經不再有效。