有些人似乎认为C的strcpy()功能是坏的还是邪恶的.虽然我承认通常最好使用strncpy()以避免缓冲区溢出,但以下(strdup()对于那些不够幸运的人来说,这个函数的实现)安全地使用strcpy()并且永远不会溢出:
char *strdup(const char *s1)
{
char *s2 = malloc(strlen(s1)+1);
if(s2 == NULL)
{
return NULL;
}
strcpy(s2, s1);
return s2;
}
Run Code Online (Sandbox Code Playgroud)
*s2保证有足够的空间来存储*s1,并且使用使得strcpy()我们不必将strlen()结果存储在另一个函数中以便稍后用作不必要的(在这种情况下)长度参数strncpy().然而,有些人用strncpy()或甚至memcpy()都需要长度参数来编写这个函数.我想知道人们对此的看法.如果您认为strcpy()在某些情况下是安全的,请说明.如果你有充分的理由不在strcpy()这种情况下使用,请给它 - 我想知道为什么使用strncpy()或memcpy()在这种情况下可能更好.如果你认为strcpy()没问题,但不在这里,请解释.
基本上,我只是想知道为什么有些人memcpy()在别人使用时使用,strcpy()而其他人则使用普通用户strncpy().是否有任何逻辑可以优先选择三个(忽略前两个的缓冲区检查)?
如何在C中正确地将char*复制到unsigned char*.以下是我的代码
int main(int argc, char **argv)
{
unsigned char *digest;
digest = malloc(20 * sizeof(unsigned char));
strncpy(digest, argv[2], 20);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想正确地将char*数组复制到unsigned char*数组.我使用上面的代码得到以下警告
warning: pointer targets in passing argument 1 of âstrncpyâ differ in signedness
Run Code Online (Sandbox Code Playgroud)
编辑:添加更多信息,我的要求是调用者在主函数中提供SHA摘要作为命令行上的字符串,主函数在内部将其保存在摘要中.SHA摘要可以使用unsigned char最好地表示.
现在的问题是我无法更改main函数(**char)的签名,因为main函数解析了它需要的其他参数作为char*而不是unsigned char*.
是memcpy()通常速度比strcpy()(上最真实的平台)?(我假设字符串的大小是已知的.)
如果我正确地记得i386汇编程序,则会有loop指令复制给定数量的字节或单词.所以它是最快的方式,而strcpy()i386汇编程序实现将'\0'在一个简单的循环中使用手动检查.
所以我觉得在x86上memcpy()要快于strcpy().
其他架构是什么?
做以下事情是否安全?
#include <stdio.h>
#include <malloc.h>
#include <string.h>
int main(void)
{
char* msg;
strcpy(msg, "Hello World!!!"); //<---------
printf("%s\n", msg);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
或者应该使用以下内容?
char* msg = (char*)malloc(sizeof(char) * 15);
Run Code Online (Sandbox Code Playgroud) 将unsigned char数组复制到另一个的最佳方法是什么?
例如:
unsigned char q[1000];
unsigned char p[1000];
strcpy (q,&p);
Run Code Online (Sandbox Code Playgroud)
上面的代码不起作用,它给我错误说"无法将参数1从unsigned char [1000]转换为char*".
我想知道为什么我在下面的代码中出现分段错误.
int main(void)
{
char str[100]="My name is Vutukuri";
char *str_old,*str_new;
str_old=str;
strcpy(str_new,str_old);
puts(str_new);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 为什么以下C代码使用strcpy对我来说很好?我尝试以两种方式使其失败:
1)我尝试strcpy从字符串文字到分配的内存太小而不能包含它.它复制了整件事并且没有抱怨.
2)我尝试strcpy了一个未被NUL终止的数组.在strcpy与printf工作就好了.我原本以为strcpy复制了chars直到NUL找到了,但没有一个存在,它仍然停止.
为什么不这些失败?我是以某种方式获得"幸运",还是我误解了这个功能是如何工作的?它是特定于我的平台(OS X Lion),还是大多数现代平台以这种方式工作?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *src1 = "123456789";
char *dst1 = (char *)malloc( 5 );
char src2[5] = {'h','e','l','l','o'};
char *dst2 = (char *)malloc( 6 );
printf("src1: %s\n", src1);
strcpy(dst1, src1);
printf("dst1: %s\n", dst1);
strcpy(dst2, src2);
printf("src2: %s\n", src2);
dst2[5] = '\0';
printf("dst2: %s\n", dst2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行此代码的输出是:
$ ./a.out …Run Code Online (Sandbox Code Playgroud) 众所周知,strcpy_s是strcpy的安全版本.
但我想知道它是如何工作的......
让我们看一些例子.
strpy_s的声明:
errno_t strcpy_s(_CHAR*_DEST,size_t _SIZE,const _CHAR*_SRC)
[点拨
char dest[5];
char* src = "abcdefg";
strcpy_s(dest,5,src);
Run Code Online (Sandbox Code Playgroud)
它将返回一个断言.
我想我能理解这一点,使用_SIZE确保我们不能复制比_SIZE更多的字符
但是......我无法理解这一点:
char dest[5];
char* src = "abcdefg";
strcpy_s(dest,10,src);
Run Code Online (Sandbox Code Playgroud)
我们仍然可以得到一个断言,那是怎么发生的?
ps,错误是:
Debug Assertion Failed
表达式:(L"Buffer is too small"&& 0)
在VS2013中
strcpy_s会检查其体内dest的大小吗?如果这是真的,怎么样?如何检查像_DEST这样的指针?
当你去删除指针时,第一个例子不起作用.当我添加null终止符时,程序要么挂起,要么没有它我得到:
Debug Assertion Failed Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 来自Visual Studio 2008
//Won't work when deleting pointer:
char *at = new char [3];
at = "tw"; // <-- not sure what's going on here that strcpy does differently
at[2] = '\0'; // <-- causes program to hang
delete at;
//Works fine when deleting pointer:
char *at = new char [3];
strcpy(at,"t");
at[1] = 'w';
at[2] = '\0';
delete at;
Run Code Online (Sandbox Code Playgroud)
那么当我使用双引号而不是strcpy时会发生什么?它们都会完美地完成字符串,调试器不会显示任何不同的内容.
在C中,我习惯于strcpy制作一个字符串的深层副本,但在C++中使用它还是"很好"strcpy还是有更好的替代方法,我应该使用它?