登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

面包会有的

... ...

 
 
 

日志

 
 

2010年12月29日  

2010-12-29 01:46:54|  分类: VC++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

众所周知,strcpy复制字符串是不安全的。
在C标准中有一个叫strncpy的函数,它带了一个n很具迷惑性,其实它也不是安全的。
VC下可以使用strncpy_s。
想要一个通用的复制字符串的方式除了手写一个类似strncpy_s函数之外,还有什么方法呢?
下面:
C/C++ code
char str[10] = { 0 };
strncpy(str, "a long long string", sizeof(str) - 1);
还是下面:
C/C++ code
char str[10] = { 0 };
memcpy(str, "a long long string", sizeof(str) - 1);
或许没有机会对str初始化的时候(如参数)这样:
C/C++ code
void foo(char *str, len)
{
 strncpy(str, "a long long string", len - 1);
 str[len - 1] = 0;
}
不过这些方法都还是依赖于程序员自己。
若是不小心,又或是程序员不懂strncpy等函数的行为,可能就会有潜在的问题。
不知道大家是怎么安全的复制字符串的?
这里不讨论std::string,本人是能用std::string的时候就会使用,但是在某些地方是没办法使用std::string,如网络协议中传输一个字符串:
C/C++ code
struct SomeProtocol
{
 char str[100];
 // other here ...
};

--------------------------------------------------------------------------------

用得不好,都不安全~

回复:[向ALL提问]大家是怎么安全的复制字符串

--------------------------------------------------------------------------------

有时候用 memcpy函数,好像也有不安全的情况

--------------------------------------------------------------------------------

如果被迫使用字符串拷贝,我比较喜欢用memcpy,这个控制力更强些。
如果是VC,StringCchCopy也是一个不错的选择。

--------------------------------------------------------------------------------

我感觉有些东西是不可避免的 只要用的时候细心就行了

--------------------------------------------------------------------------------

 用std:string最安全

--------------------------------------------------------------------------------

你想要的安全是什么标准呢?不越界,线程安全还是啥。如果仅仅是指针合法和不越界,还算简单。要线程安全,标准库的都不是线程安全的吧,自己得加锁互斥实现。

--------------------------------------------------------------------------------

想要安全的话,没有问题,自己重写一遍字符串拷贝函数,在函数内部将所有可能发生的错误都进行相应的判断和处理,只要你想得到,这个函数绝对安全。
但是相对的,效率就没了,工具而已,会用就安全,不会用或者瞎用就危险,就这么简单。

--------------------------------------------------------------------------------

C/C++ code
char to[LEN + 1];
snprintf(to, sizeof(to), "%s", from);

--------------------------------------------------------------------------------

你想要的安全是什么标准呢?不越界,线程安全还是啥。如果仅仅是指针合法和不越界,还算简单。要线程安全,标准库的都不是线程安全的吧,自己得加锁互斥实现。
首先,这里讨论的肯定不是线程安全问题。
想要安全的话,没有问题,自己重写一遍字符串拷贝函数,在函数内部将所有可能发生的错误都进行相应的判断和处理,只要你想得到,这个函数绝对安全。
但是相对的,效率就没了,工具而已,会用就安全,不会用或者瞎用就危险,就这么简单。
对于自己写这个问题,在团队中是很难让一个团队中的每个人都会去调用自己写的函数。
而如果仅仅是自己个人写程序的话,那没什么意义了。
至少本人自己写程序是基本上都用std::string的,就是在某些不得已的情况下需要上述方法来处理也是没问题的,自己明白怎么用好,那写不写一个函数来处理这个问题的意义就不重要了。

--------------------------------------------------------------------------------

std::string

--------------------------------------------------------------------------------

C/C++ code
char to[LEN + 1];
snprintf(to, sizeof(to), "%s", from);
这个是可以,但是snprintf是C99函数,无奈VC不支持C99,也就只能在gcc下用了。
VC有个_snprintf但是其表现行为和snprintf不一样,不会自动添加0。
跨平台无奈中。。。

--------------------------------------------------------------------------------

memeset()先初始化,再assert(),最后memcpy();
这三者结合起来,呵呵。
反正任何东西都有两面性,要看你怎么用,如果你想用得最安全,采用迭代子,一个一个地复制,但效率欠缺。
综上所术:it all depends on ourselves.

--------------------------------------------------------------------------------

带长度限制的应该相对安全些,也便于检查

--------------------------------------------------------------------------------

没什么不安全的,不过习惯在复制后把最后一个字符设置成'\0'

貌似我都是用
char str[10] = { 0 };
strncpy(str, "a long long string", sizeof(str) - 1)

回复:[向ALL提问]大家是怎么安全的复制字符串

--------------------------------------------------------------------------------

strncpy
memcpy

--------------------------------------------------------------------------------

没有绝对的安全,也没有绝对的不安全。
奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中!

--------------------------------------------------------------------------------

没有绝对的安全,也没有绝对的不安全。
奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中!
传说中的机器?

--------------------------------------------------------------------------------

库函数没有绝对的安全,在使用的时候需要程序员自己控制。

--------------------------------------------------------------------------------

string也不安全,会有堆分配失败问题。

--------------------------------------------------------------------------------

strncpy,一般都用这个。

--------------------------------------------------------------------------------

- 原生字符串分ascii、多字节、unicode共3种
- 显然字符串的宽度为一个字符单元。在前两种下面等于字节数,后一种下面等于字数(一个字等于两个字节)。
- 用memcpy类的内存拷贝函数拷贝字符串是一种很不负责任的做法。
- 学校里教c语言居然还只是用纯ascii来教,无语... 字符串得用TCHAR表示,相应的函数为_tcscpy、_tcsncpy等。字符串还可能只用wchar_t或只用char。
- 回到该问题:栈内只能申请到长度很有限且固定的字符串。而堆中申请的字符串可以很长却有内存分配失败的可能。不管是堆还是栈,面临的字符串安全问题有两个:一个是缓冲区溢出、一个是无零字符结尾。使用类可以自动化的正确处理字符串。但因为字符串的长度在处理中可能变化,因此当前大多数字符串类是在堆中放置字符串的。对堆分配失败的处理就成了另一个问题。

--------------------------------------------------------------------------------

  评论这张
 
阅读(797)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018