标准的strcpy,strncpy等C风格的char函数基本都没有缓冲区溢出校验,都算是高危函数,标准版都是基于memcpy实现,memcpy可能会出现覆盖,且4字节一次拷贝。除了给出这几个实现,开始的单字节是简化版。
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长度不足直接在后面补加
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。