在一個簡單的網路程式,似乎有滿多人都會這樣寫(轉自對岸教學網站):
char tmp[32];
memset( tmp, '\0', sizeof(tmp));
int ret = recv( sock, tmp, sizeof(tmp), 0 );
printf("%s\n", tmp);
把 buffer 填滿固然是一件好事,但是字串填滿之後,結果沒有\0了
就會發生意想不到的事情,可能會出現程式記憶體存取違規的問題
( 字元陣列的結尾正常結束都要有個 \0 才是正確的 )
假設我們不看 ret 回傳收到多大的資料,考慮使用 strcat 來把回傳的 buffer
串到更大的 buffer 字元陣列,應該要扣掉1來使用,避免發生記憶體存取違規!
char tmp[32];
int ret;
if( (ret = recv( sock, tmp, sizeof(tmp) - 1, 0 ) ) > 0 ) {
tmp[ret] = 0x0;
printf("%s\n", tmp);
}
PS. 經多名友人反應,本文再度稍做補充,順便補上錯誤檢查,避免造成更多誤會 XD
基本上這篇很單純寫給初學者看的,平常實甚忙碌,閒暇時逛網看到對岸常見教學
網站文章,出現了離譜的範例,而很多人又習慣拷貝教學文章四處轉貼。
這篇文章的主旨不外乎探討一般簡單的範例會把收到的資料透過 printf 出來或做 strcat
而在這個時候如果字元陣列尾端沒有 \0 就會引起 Access Violation 記憶體存取違規。
對於 memset 的操作,也是原本的文章這樣寫,純粹只是直接拷貝沿用舉例,
很明顯是 O(n) 的時間複雜度,當然不好,但這根本不是我發此文討論的重點呀 XDD
另外,這篇也不是要探討傳輸 binary data 的應用,更與 HTTP 協定無關。