我有一段代码:
new->name = zalloc(sizeof(char) * strlen(name) + 1);
if (!new->name)
goto alloc_failed;
strcpy(new->name, name);
如果strcpy()不受欢迎(即使名称的空间已预先分配),则是一般用途。只是出于安全目的而好奇。Is最好使用strncpy()或srtlcpy()。
您的编码示例有一些小问题:
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()
,它可能在您的平台上可用,也可能不可用,但对于其他地方来说是一个不错的选择。最好避免CCD_ 17 OTOH。它是一个标准的C函数,但它的语义与C库的其他部分不一致,因此经常被误用:
著名的缺点是,如果源字符串比size参数长,则
strncpy()
不会在目标的末尾添加' '
。CCD_ 20可以做到这一点,但可能不是很有效。当源字符串短于size参数时,
strncpy
会出现一个鲜为人知的副作用:目标数组一直用' '
填充到最后。如果目标阵列比源阵列长得多,那么使用strncpy()
来避免缓冲区溢出是非常低效的。
当您知道数据的最大可能限制是多少时,应该使用strcpy,当它是用户定义的时,则应该使用strncpy。
您在这个例子中使用strcpy是可以的。