C++中string字符串类以及函数c_str()分析

#include <iostream>
#include <string>

using namespace  std;


int main()
{
    string s="12345";
    const char* p=s.c_str(); //用C语言的方式定义一个指针p,使它指向C++中字符串s
    //c_str()函数就是C++ string类中为了兼容指向C语言字符串而提供的一个函数
    
    cout<<p<<endl;
    
    s.append("abcd");
    
    cout<<p<<endl;
    
    return 0;
}

想想这个程序会输出什么呢?const char* p=s.c_str(); 这句代码已经定义了一个指针使它指向s字符串,所以你是不是觉得程序的输出会是:12345 12345abcd呢?

好来看一下实际的程序输出:

delphi@delphi-vm:~$ ./a.out
12345
12345
delphi@delphi-vm:~$ 
程序的两次输出都为12345,嗯?这个就有点奇怪呢哈?

我们来看一下实际的原因吧。

在C++string类中,维护了一个m_cstr的指针,这个指针第一次指向"12345"这偏内存区域,其中const char* p也指向"12345"这遍内存区域。然而,经过s.append("abced")这句代码的时候,m_cstr就以及指向了"12345abced"这遍内存区域了,但是const char* p还是指向原来的"12345"这遍原来的内存区域(原来的内存区域以及被释放了,其实p以及成为野指针了),所以2次打印就输出一样的结果了。来我们来吧程序稍微的改改,就可以得到了正确的结果。

#include <iostream>
#include <string>

using namespace  std;


int main()
{
    string s="12345";
    const char* p=s.c_str();
    
    cout<<p<<endl;
    
    s.append("abcd");
    
    p=s.c_str();//重新让指针p指向m_cstr所指向的内存区域,就可以得到正确的结果
    
    cout<<p<<endl;
    
    return 0;
}

输出结果为:

delphi@delphi-vm:~$ g++ test.cpp
delphi@delphi-vm:~$ ./a.out
12345
12345abcd

再来看一个很奇诡的例子:

#include <iostream>
#include <string>

using namespace  std;


int main()
{
    const char* p="12345";
    string s="";
    
    s.reserve(10); //将s字符串所代表的的存储空间重置为10个大小的字节
    
    for(int i=0;i<5;i++)
    {
        s[i]=p[i]; 
    }
    
    if(!s.empty())
    {
        cout<<s<<endl; //是不是很期待输出 12345呢??
    }
    
    return 0;
}

原因分析:

在for执行之前,m_cstr指向一篇10字节的内存区域,字符串长度为0。然后for循环执行后,m_cstr所指向的内存区域的前5个字节的确变成了,12345,但是它的长度m_length还是0,所以输出结果就是什么都没有的原因了。

#include <iostream>
#include <string>

using namespace  std;


int main()
{
    const char* p="12345";
    string s="";
    
    s.reserve(10);
    
    for(int i=0;i<5;i++)
    {
        s[i]=p[i];
    }
    
    if(!s.empty())
    {
        cout<<s<<endl;
    }
    
    for(int i=0;i<5;i++)
    {
        cout<<s[i]<<endl;// 输出1 2 3 4 5
    }
    
    cout<<s.length()<<endl;// 输出 0
    
    
    return 0;
}

 

 

总结:这2个例子告诉我们,C++标准库中的string类,通过一个指针来保存一个一遍内存空间,其实它的内部也有一个成员变量来保存这偏内存空间所存放字符串的长度。还有一点就是用C++编程(面向对象)就尽量避开用C语言(面向过程)的编程习惯。
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

repinkply

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值