那些年,踩過的坑
阿新 • • 發佈:2019-01-25
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. 這樣可以防止後續對該指標進行操作時出錯, 先看一個不好的風格.該程式風格不好(儘管正確):
- #include<stdio.h>
- int main()
- {
- int *p = newint(5);
- delete p;
- return 0;
- }
現在假設程式很大,不小心又釋放了一次,即:
-
#include<stdio.h>
- int main()
- {
- int *p = newint(5);
- delete p;
- delete p;
- return 0;
- }
執行程式,程式會crash, 這就是記憶體過度釋放的後果, 如果程式很大,就很不好找. 而且,編譯器提示的資訊也非常有限。來看看下面的程式,在釋放後將指標置為NULL:
- #include<stdio.h>
- int main()
- {
- int *p = newint(5);
- delete p;
-
p = NULL; // 如果沒有這一個語句,程式就會crash
- delete p; // 沒關係, 但通常會對是否為NULL進行判斷, 這樣就更需要將p置為NULL了
- p = NULL;
- return 0;
- }
結果程式可以正常執行,這就是將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所指向的區域已經不再有效。