C - 一般使用strcpy

时间:2015-04-20 02:01:17

标签: c buffer buffer-overflow strcpy strncpy

我有这段代码:

new->name = zalloc(sizeof(char) * strlen(name) + 1);
if (!new->name)
    goto alloc_failed;
strcpy(new->name, name);

即使名称空间已预先分配,strcpy()也不赞成使用。只是为了安全的目的而疑惑。最好使用strncpy()或srtlcpy()。

2 个答案:

答案 0 :(得分:1)

您的编码示例有一些小问题:

new->name = zalloc(sizeof(char) * strlen(name) + 1);
if (!new->name)
    goto alloc_failed;
strcpy(new->name, name);

分配的大小计算为sizeof(char) * strlen(name) + 1。如果您坚持按sizeof(char)乘以定义等于1,则至少应该写:sizeof(char) * (strlen(name) + 1)。除此之外,在此示例中使用strcpy很好,但将大小存储在局部变量中并使用memcpy会更有效:

{
    size_t size = strlen(name) + 1;
    new->name = zalloc(size);
    if (!new->name)
        goto alloc_failed;
    memcpy(new->name, name, size);
}

另请注意,POSIX系统strdup()使用malloc执行相同的操作。如果zalloc()malloc()上的瘦包装器,它从单个大小的参数中将内存分配并初始化为零,则可以使用strdup()作为此代码的简单替换。如果它是自定义内存分配方案,您还应该提供zstrdup(),因为重复字符串在许多C程序中很常见。

关于样式的另一个小注释:如果本地编码约定宽恕它,那么使用goto就好了,但最好不要使用明显的C ++关键字,例如newdelete作为普通标识符。

关于strlcpy(),它可能在您的平台上提供,也可能不提供,但对其他地方来说是个不错的选择。最好避免使用strncpy() OTOH。它是一个标准的C函数,但它的语义与C库的其余部分非常不一致,因此经常被滥用:

  • 如果源字符串长度超过size参数,则着名的缺点是strncpy()在目标末尾没有'\0'snprintf(dest, size, "%s", src);会这样做但可能效率不高。

  • 当源字符串短于size参数时,会发生strncpy的鲜为人知的副作用:目标数组一直填充'\0' 到最后。如果目标数组远远长于源,则使用strncpy()来避免缓冲区溢出是非常低效的。

答案 1 :(得分:-1)

当你知道可能的数据的最大限制是什么时,你应该使用strcpy,当用户定义时,你应该使用strncpy。

你在这个例子中使用strcpy是可以的。