我有这段代码:
new->name = zalloc(sizeof(char) * strlen(name) + 1);
if (!new->name)
goto alloc_failed;
strcpy(new->name, name);
即使名称空间已预先分配,strcpy()也不赞成使用。只是为了安全的目的而疑惑。最好使用strncpy()或srtlcpy()。
答案 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 ++关键字,例如new
和delete
作为普通标识符。
关于strlcpy()
,它可能在您的平台上提供,也可能不提供,但对其他地方来说是个不错的选择。最好避免使用strncpy()
OTOH。它是一个标准的C函数,但它的语义与C库的其余部分非常不一致,因此经常被滥用:
如果源字符串长度超过size参数,则着名的缺点是strncpy()
在目标末尾没有'\0'
。 snprintf(dest, size, "%s", src);
会这样做但可能效率不高。
当源字符串短于size参数时,会发生strncpy
的鲜为人知的副作用:目标数组一直填充'\0'
到最后。如果目标数组远远长于源,则使用strncpy()
来避免缓冲区溢出是非常低效的。
答案 1 :(得分:-1)
当你知道可能的数据的最大限制是什么时,你应该使用strcpy,当用户定义时,你应该使用strncpy。
你在这个例子中使用strcpy是可以的。