C++ 在函数中声明string和字符数组的一些特性

本文探讨了C++中string类型的生命周期管理问题,通过示例代码展示了string变量如何超出函数作用域仍可访问,以及其地址空间的复用特性。同时对比了char[]和malloc分配空间的情况。

在函数中声明string

char * test(void )
{
    string test;
    test = "yinjianwen";
    return (char *)test.c_str();
}
int main()
{
    enum tesT {a,b=5,c,};
    printf("a = %d\n", a);
    char *p;
    p = test();
    printf("%s\n", p);
    p[2] = '*';
    printf("%s\n", p);
    test();
    printf("%s\n", p);
}

以上面这串代码为例,我们可以得到如下结果:

a = 0
yinjianwen
yi*jianwen
yinjianwen

说明,在函数中申请的string变量的生命周期是超出了函数外的,而且这个地址空间是被重复使用的。
如果强行delete是可以清空的,但是会在运行的时候报错,这应该是不保险的。
不要想free了,free是用来对付指针指引的地址空间的。

如果把string替换为char []

这样就回到C语言中的情况,一但退出函数,这个地址是被回收了的,里面的内容被修改成什么样是不可控制的。

如果是malloc分配的空间呢?

经验证,用户分配的空间是在堆上面的,而函数能够自动释放的空间是计算机自动分配在栈上面的内容。malloc恰恰是用户分配在堆上面的那种情况,这就需要用户自动释放,如果不释放,就会一直存在。但是如果你不返回地址给函数外的用户,这段空间就被遗失在茫茫内存中,找不到了,虽然它是存在的。

### C++ 中 `std::string` 类与字符数组性能对比 在 C++ 编程中,处理字符串数据有两种主要方式:使用 `std::string` 传统的字符数组(C-style strings)。为了评估这两种方法之间的性能差异,可以从多个方面进行分析。 #### 内存分配机制 对于 `std::string` 对象而言,其内部实现通常涉及动态内存分配。这意味着创建、复制销毁这些对象时会有额外开销[^2]。相比之下,固定大小的字符数组不需要运行时分配新空间,因此可能更高效于某些场景下: ```cpp // 使用 std::string 的例子 #include <iostream> #include <string> int main() { std::string str = "example"; } // 使用字符数组的例子 char char_array[] = "example"; ``` 然而,在实际应用中,除非频繁执行大量短生命周期的小型字符串操作,否则这种差异往往不明显。 #### 字符串连接效率 当涉及到字符串拼接时,`std::string` 提供了更为简便的方法来构建复杂的字符串表达式。虽然每次调用加号运算符 (`+`) 或者成员函数 append 都会触发一次新的分配过程,但是现代编译器优化技术已经大大减少了这部分成本。而对于字符数组来说,则需要手动管理缓冲区并确保不会发生越界写入等问题。 #### 函数参数传递 作为函数参数传入时,`const char*` 形参形式下的字符指针能够避免不必要的拷贝动作;而如果采用按值传递的方式给定一个完整的 `std::string` 实例则可能导致深拷贝的发生。不过,通过引用或常量引用来接收此类参数同样能有效规避此问题,
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值