关于const_cast(str.c_str())的使用问题

来源:互联网 发布:不允许写访问 mac 编辑:程序博客网 时间:2024/06/05 10:45

偶然一次在写代码时用到了const_cast<char*>(str.c_str()),后来在调试程序的时候发现了问题。本来VC6和gcc的string应该是在相互赋值时不拷贝的,只有当其中一个string对象改变之后,两个string对象才会指向不同的值。但是,在那段代码里强转之后,string变成了类似于引用的一种情况,两个string完全同质了,改变一个另一个也变了。


出现问题的帖子:

http://topic.csdn.net/u/20100324/13/058a7477-4bfd-4210-a72f-1e8b78bd53dd.html


关于此问题进一步讨论的帖子:
http://topic.csdn.net/u/20100329/11/fd54c4a9-12e7-41c5-ba38-1bedfa8e8ecc.html?seed=422802561&r=64276936#r_64276936

[一些经典的解答]
turbocamel:
stl的string不是处理文本的,string当中包含的二进制数据,所以你用c_str()是不会自己加0的,那个0肯定是原来就有,如果原来没有那c_str()也不会给你加上。
至于const_cast的使用,个人认为如果自己用,只要控制好没什么问题,如果要提供给其他人使用,那就小心了,还是不要转换为妙。如果说这个会破坏引用计数,应该不会。引用计数在string内部维护,而const_cast是对c_str()的返回值进行操作,此时已经脱离string对象,所以引用计数不会被破坏。
但是VC6的string是存在bug的。可以参考http://support.microsoft.com/kb/813810

实际上我一般不使用c_str这个接口,因为使用这个接口把内部指针暴露出来增加了危险性。
而且,对于自己写的代码来说是可以完全使用string对象来控制的,不需要内部的指针,除非别人需要char*,此时才会调用这个接口,得到char*,但问题是,这个char*给别人用已经完全把自己的安全交给别人了。

Jinhao:
basic_string 正是处理字符串的,不然和vector没区别了. 当然,并不是只有char, wchar_t序列的串才叫字符串.
c_str()最后以什么结束?
对于std::string/std::wstring.可以明确地说,c_str()返回的buffer是以0结束.
c_str()返回的buf的长度是 sizeof(CharT) * ("字符"个数+1) .及保证[begin, end)原则.
而最后以什么结束,也就是*end会是什么?
这是以basic_string<T>::value_type() 来决定,对于内建类型,char/wchar_t的 显式默认构造函数得到的值都是0.
而对于basic_string来说,没有"结束符"的说法,也就是说std::string不以0为结束.
而c_str()返回的结果最后以0结束并不与此矛盾.

VS2003开始就取消了cow和引用计数,取消是因为效率问题.而不是安全问题...(turbocamel:不明白你的意思,按说cow和引用计数是为了提高效率才有的特性,取消这两个特性会降低string的效率,而不是提高效率,但是会增加稳定性。)在多线程下,如果还保证COW,那只会让效率更低...取消COW是为了保证不同的string对象拥有不同的buffer,降低资源竞争.
如果在单核多线程情况下,保证COW的std::string的线程安全,效率开销就是进/出锁的开销,这开销已经不小.
如果在多核多线程情况下,还保证COW的std::string的线程安全,造成资源竞争,效率则会大大降低

[对于上述问题的一些测试]
大致总结了5个问题。


原创粉丝点击