实现strcpy:如果目标比源短,该怎么办?

时间:2014-12-13 14:04:34

标签: c string

我的strcpy功能出现问题。我在不使用string.h标题的情况下编写它。它有效,但是,如果dst比src短?我怎么检查它?因为如果dst是示例"car"和src "green"会是错误吗?

#include <stdio.h>
#include <stdlib.h>

char* strcpy(char* dst, const char* src) {
    char* origDest =dst;

    while(*src != '\0') {
        *dst = *src;
        dst++;
        src++;
    }
    return origDest;
}

int main()
{
    char A[] = {"Blackcar"};
    char B[] = {"white"};
    char *C[10];

    *C = strcpy(&A, &B);

    printf("%s", *C);

    return 0;
}

另外,我应该使用malloc这个功能吗?

3 个答案:

答案 0 :(得分:3)

无法以优雅的方式检查它,因为您无法知道dststrcpy的长度。也许在您的main函数中,您可以使用终止A来检查字符串\0的长度,但不能保证dst可能不是垃圾数据或使用\0清除。这就是为什么strcpy可以轻松获得缓冲区溢出(Why should you use strncpy instead of strcpy?

的原因之一

所以我的建议是在你的函数中添加一个length参数,这意味着要复制多少字节。或者您可以自己实现strncpy的一个版本。

PS:即使使用strncpy,程序员也必须确保传递给strncpy的参数有效且正确。

答案 1 :(得分:2)

strcpy函数无法知道目标缓冲区的大小。这就是为什么strcpy被弃用的原因:你无法通过查看函数的调用来判断它是否被正确使用。

如果目标缓冲区不够大,strcpy具有未定义的行为:语言规则表明任何事情都可能发生。实际上,它会覆盖一些内存:缓冲区溢出。程序员应该确保他们只安全地使用strcpy。这是程序员的责任,而不是函数实现者的责任,实际上,实现者无法做任何事情:目标缓冲区的大小无法检查。

strcpy的目标缓冲区不需要包含有效字符串。这是对strcpy

的完全有效使用
char dst[10] = "car";
char src[12] = "green";
strcpy(dst, src);

目标缓冲区长度为10个字节,对于最多9个字符的字符串(加上一个终止空字节)就足够了。它恰好在那一刻包含一个较短的字符串,但这并不重要。在复制之前,dst是一个包含类似

之类的10字节数组
'c', 'a', 'r', 0, 'J', 'U', 'N', 'K', '.', '.'

(0字节之后可以是什么,这只是一个例子)。复制后,dst包含

'g', 'r', 'e', 'e', 'n', 0, 'N', 'K', '.', '.'

换句话说:strcpy并不完全将字符串复制到字符串。它将字符串复制到缓冲区。复制后,该缓冲区包含一个字符串。重要的是目标缓冲区足够大以容纳字符串。

strcpy写入现有缓冲区,它不需要也不应该调用malloc。有一个不同的函数strdup,它复制一个字符串并为它分配足够的内存;此函数不将目标缓冲区作为参数(如何:它创建目标缓冲区)。

答案 2 :(得分:1)

char* strcpy(char* dst, const char* src)永远不会将'\0'写入dest! 建议这就是为什么OP说“我的strcpy功能有问题”。

如果没有传递额外的参数来了解目的地的大小,那么就没有办法,但至少确保dest被正确终止。

char* BB_strcpy(char* dst, const char* src) {
    char* origDest =dst;

    while(*src != '\0') {
        *dst = *src;
        dst++;
        src++;
    }
    *dst = 0;   // add this
    return origDest;
}

标准strcpy()不分配内存。 OP的版本也不应使用malloc()