C語言危險函數

來源:互聯網
上載者:User

定義字串會自動在後邊添加\0. char *p = "hello";
for(i=0;i<7;i++)
{
     printf("%d\n",p[i]);
} 104 101 108 108 111 0 115 

注意危險函數:
1、危險函數gets()函數,應該使用fgets() char *gets (char *__s)  //從標準輸入讀入字串 使用 char *fgets(char *s, int size, FILE *stream),其中第二個參數使用 buf 的 size 就可以, fgets 函數會保證最後一個位元組是’\0’且不會越界。

#include <stdio.h>
#include <string.h>

void main()
{
    char buf[5] = {0};
    int i = 0;

    fgets(buf,5,stdin);
    printf("buf = %s\n",buf);
    for(i=0;i<5;i++)
    {  
        printf("buf[0] = %d\n",buf[i]);                                                                                                                                 
    }  
}
2、scanf 很危險 禁止使用  int scanf (const char *__restrict __format, ...); 在程式輸入字串的時候,如果輸入的字串超過了指定的長度,會使程式崩潰,造成溢出錯誤 使用 fgets,然後自己解析字串。
3、sscanf 很危險 限制使用  sscanf (const char *__restrict __s, const char *__restrict __format, ...),也存在溢出問題。 建議使用 strlcpy, strtol, atoi 等函數進行解析, 特別是sscanf 的 format 參數裡有%s 時禁止使用
4、sprintf 很危險 禁止使用  int sprintf (char *__restrict __s, const char *__restrict __format, ...) ;如果s小於要寫入的字串大小,將會超出s的大小,造成記憶體溢出。
使用 int snprintf(char *str, size_t size, const char *format, ...) ; size要等於str的大小,比如char str[5],size=5,則str[0]-str[3]存放格式化的字串,str[4]存放'\0';如果size=6,則會報記憶體溢出;如果size=4,不報錯,但是少用了,並且會在str[3]的地方存放‘\0’; snprintf函數是sprintf函數的更加安全版本,考慮到字串的位元組數,防止了字串溢出。函數形式為: int snprintf(char *restrict buf, size_t n, const char * restrict  format, ...);。最多從源串中拷貝n-1個字元到目標串中,然後再在後面加一個0。所以如果目標串的大小為n 的話,將不會溢出。
size 的作用就是限制往str寫入不超過size個位元組(包括了結尾的'/0')。 因為sprintf()函數如果成功的話,返回成功寫入的位元組數(字元數),我就一直以為snprintf()函數也是如此,也就是snprintf()函數不會返回大於size的整數。 看下面一段手冊內容: The functions snprintf() and vsnprintf() do not  write  more than size bytes (including the trailing ’/0’). If the output was truncated due to this limit then the return value is the number of  characters (not including the trailing ’/0’) which would have been written to the final string if enough space had been  available.  Thus,  a  return value  of  size  or more means that the output was truncated. 如果輸出因為size的限制而被截斷,傳回值將是“如果有足夠空間儲存,所   應  能輸出的字元數(不包括字串結尾的'/0')”,這個值和size相等或者比size大。也就是說,如果可以寫入的字串是   "0123456789ABCDEF"   共16位,但是size限制了是10,這樣 snprintf() 的傳回值將會是16 而不是   10   。 上面的內容還說,如果傳回值等於或者大於size,則表明輸出字串被截斷了(truncated)。
5、vsprintf 很危險 禁止使用 使用 int vsnprintf(char *str, size_t size, const char *format,va_list ap)

6、strcpy  很危險 禁止使用 char *strcpy (char *__restrict __dest, const char *__restrict __src) 此處不能保證dest的大小>str的大小,如果超出,將很危險。 char *strncpy (char *__restrict __dest, const char *__restrict __src, size_t __n) 指定的是src的長度,如果src的長度大於n,那麼dest的字串將會不是以0結尾的。 strncpy 中危險 限制使用建議使用 strlcpy. strncpy 不能保證最後一個字元是’\0’,需要其他代碼來設定字串結束符’\0’ 使用 size_t strlcpy(char *dest, const char *src, size_t size),strlcpy 函數會保證最後一個位元組是’\0’且不會越界,標準 c庫裡沒有實現,但我們在 swos 庫裡有實現, uclibc 裡有實現。特別需要注意 strlcpy 的最後一個參數是目標緩衝區的大小 sizeof(dest),而不能是 strlen(src).

7、strcat  很危險 禁止使用 char *strcat (char *__restrict __dest, const char *__restrict __src) 
//如果src+dest>dest,將出現溢出。 char *strncat (char *__restrict __dest, const char *__restrict __src,  size_t __n) //如果src+n+dest大於dest的空間,將不是以0結尾。   
使用 char *strlcat(char *dest, const char *src, size_t  n),strlcat 函數會保證最後一個位元組是’\0’且不會越界,標準 c 庫裡沒有實現該函數,但我們在 swos 庫裡有實現,uclibc 裡有實現。 特別需要注意 strlcat 的最後一個參數是目標緩衝區的大小 sizeof(dest),而不能是 strlen(src).

8、strdup  中危險 謹慎使用 char *strdup (const char *__s); strdup 返回的指標,需要調用 free 函數進行釋放。 strdup函數裡會 malloc 一塊記憶體並返回,需要調用者去 free,比較容易忘記 free,導致記憶體泄露。 char *
__strdup (const char *s)
{
  size_t len = strlen (s) + 1;
  void *new = malloc (len);

  if (new == NULL)
    return NULL;

  return (char *) memcpy (new, s, len);
}
9、bcopy 中危險 禁止使用 非常用函數,建議使用 memcpy 或者 strlcpy。

10、system 中危險 禁止使用使用 swsyscmd 或者直接使用 C 庫函數。 system 函數需要繼承當前進程的環境空間,如果當前進程比較龐大時,需要的空間就越大,當記憶體不夠時 system 裡的命令就不 會被執行。
特別注意項:
A.        對於  memcpy ,  memset ,  strlcpy ,  strlcat  請確保傳入的  size  不能超過目標緩衝區的大小。
B.        幾乎所有的  C  庫函數都不會對null 指標進行判斷,因此我們傳入的參數指標需要確保不是 NULL 。
C.        使用  str 族函數需要注意, str 族函數只能處理帶字串結束符的文本資料,針對加密,數位簽章等會產生非文本資料的處理不能使用 str 族函數,應該使用 mem 族的函數。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.