標準的strcpy,strncpy等C風格的char函數基本都沒有緩衝區溢出校驗,都算是高危函數,標準版都是基於memcpy實現,memcpy可能會出現覆蓋,且4字節一次拷貝。除了給出這幾個實現,開始的單字節是簡化版。c++
char* strcat(char* des, const char* src) // const代表爲輸入參數 { assert((des!=NULL) && (src!=NULL)); char* address = des; while(*des != '\0') // 移動到字符串末尾 ++des; while(*des++ = *src++) ; return address; }
char* strcpy(char* des, const char* src) { assert((des!=NULL) && (src!=NULL)); char *address = des; while((*des++ = *src++) != '\0') ; return address; }
int strcmp(const char *s1, const char *s2) { while (*s1 == *s2++) if (*s1++ == '\0') return (0); return (*(unsigned char *)s1 - *(unsigned char *)s2); }
int strlen(const char* str) { assert(str != NULL); int len = 0; while((*str++) != '\0') ++len; return len; }
char * strcat(char *restrict dst, const char *restrict src) { const size_t dstlen = strlen(dst); const size_t srclen = strlen(src); memcpy(dst+dstlen, src, srclen+1); return dst; }
char * strcpy(char * restrict dst, const char * restrict src) { const size_t length = strlen(src); memcpy(dst, src, length + 1); return dsth; }
char * strncpy(char * restrict dst, const char * restrict src, size_t maxlen) { const size_t srclen = strnlen(src, maxlen); if (srclen < maxlen) { memcpy(dst, src, srclen); memset(dst+srclen, 0, maxlen-srclen); } else { memcpy(dst, src, maxlen); } return dst; }
void BYTE_COPY_FWD(void * dstpp, const void * srcpp, size_t len){ int i=0; while(i < len){ ((char*)dstpp)[i] = ((char*)srcpp)[i]; i++; } } void WORD_COPY_FWD(void * dstpp, const void * srcpp, size_t& len){ int i=0; while(i*4 <= len-4){ ((int*)dstpp)[i] = ((int*)srcpp)[i]; i+=1; } len -= i*4; } void BYTE_COPY_BWD(void * dstpp, const void * srcpp, size_t len){ while(len-- > 0){ ((char*)dstpp)[len] = ((char*)srcpp)[len]; } } void WORD_COPY_BWD(void * dstpp, const void * srcpp, size_t& len){ while(len/4 >= 1){ ((int*)dstpp)[len/4] = ((int*)srcpp)[len/4]; len -= 4; } } void *xhymemcpy (void *dstpp, const void *srcpp, size_t len) { unsigned long int dstp = (long int) dstpp; size_t ol = len; int copyedLen=0; if (len >= 4) { len -= (-dstp) % 4; BYTE_COPY_FWD (dstpp, srcpp, (-dstp) % 4); WORD_COPY_FWD (dstpp, srcpp, len); copyedLen += (-dstp) % 4 + (len/4)*4; } BYTE_COPY_FWD ((char*)dstpp+copyedLen, (char*)srcpp+ol/4, copyedLen); return dstpp; } void *xhymemmove (void *dstpp, const void *srcpp, size_t len) { unsigned long int dstp = (long int) dstpp; unsigned long int srcp = (long int) srcpp; if (srcp - dstp >= len) { return memcpy(dstpp,srcpp,len); }else{ dstp += len; if (len >= 4) { len -= (dstp) % 4; BYTE_COPY_BWD (dstpp, srcpp, (dstp) % 4); WORD_COPY_BWD (dstpp, srcpp, len); } BYTE_COPY_BWD (dstpp, srcpp, len); return dstpp; }; }
assert 若是表達式值爲假,那麼它先向stderr打印錯誤信息,而後經過調用 abort 來終止程序運行。只在 DEBUG 下生效。宏函數
危險函數
gets,stpcpy,sprintf等沒有檢查n直到結尾,會溢出
strncpy,fgetc,read等 當dst長度不足直接在後面補加rest