标准的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长度不足直接在后面补加


梦想家
107 声望76 粉丝