容器类(1)Vector(re迭代)

why vector,而不是内置数组(包括定长数组int[5],和动态数组int *arr=new int[n]):
key:vector可以很大程度地避免下标越界,缓冲区溢出,内存泄露
1)自动析构,因为是局部对象。因为是自动析构,所以不用关心释放问题了
2)异常安全的一部分(《TC++PL》),同样也是因为是局部对象,定长数组也能自动析构,但不能动态分配
3)小心使用,可以避免缓冲区溢出:可以动态调整大小,只要不超过它们的最大大小(要知道这个大小,就可以调用max_size成员函数),它们就可以自动增长到足以容纳你放进去的数据
4)小心使用,可以避免下标越界:通过使用at()抛出异常【?????todo:when使用at,[]?非大循环是否都应该用at】,来下标越界检查
5)vector知道自己的大小,通过size()成员函数
6)容器类还可以和算法相结合:比如删除在vector内,“与某值相等”的第一个元素、或“与某值相等”的所有元素(《C++ STL》p154)
7)有很多丰富的接口

why not vector(缺点 vector):
1)使用at有性能损失(因为有条件判断。所以,如果在一些循环中要考虑是否要使用);而,[]会可能造成下标越界
2)!注意:容量只会越来越大:大小和容量的区别,为了性能考虑,不会自动缩减容量
3)内存重新分配问题,造成的代价:1)性能损失 2)迭代器失效
4)迭代器失效

when 迭代器失效:内存重新分配(隐式(插入操作),显式(reserve)),插入操作(插入点之后的失效),删除操作(指向被删除的所有元素的间接引用全部失效,删除点之后的失效),缩减容量(shrink_to_fit,或用间接技巧swap)

Key
     1)vector可以很大程度地避免下标越界,缓冲区溢出,内存泄露。尽量使用at
     2)when迭代器失效
     3)!注意:大小容量的区别,clear,reserve,resize,以及其他删除操作都不会减少容量,所以即便clear之后容量也不会改变
     4)reserve和resize区别

使用技巧
how:
1)尽量(第一选择)使用at来读取容器元素,而不是[]:通过at才能避免下标越界的问题。如果使用[],则仍然会导致这2种问题,因为[]<<只能>>存在于容器内的元素操作,这意味着[]和容器大小是息息相关的。(《Exceptional C++ Style》电子版p16)
2)when如果能预知大约多少空间,则事先reserve内存
3)how如何确保插入不会导致内存重新分配
(《c++ primer》p286)
4)如果不确定初始值,那就尽量少用值初始化vector,因为可能会有性能损失
《C++STL》p149
5)尽量避免使用很多vector,可能会导致内存大量浪费,因为vector不会缩减容量
6)vector只能减少大小,无法减少容量,只有一个技巧来间接缩减容量。C++11提供了shrink_to_fit来直接缩减容量:
    注意:无论是间接缩减容量,还是shrink_to_fit,都会使所有间接引用失效:
《Effective STL》电子版p77
7)尽量使用vector的push_back来添加元素,因为它总是安全的。而用resize则可能不安全,reserve之后用ivec[3]=..几乎肯定不安全(《Exceptional C++》p17)

### 关于洛谷平台上RE错误的原因及解决方案 #### 错误定义 运行时错误(Runtime Error, RE)是指程序在执行过程中遇到了无法处理的情况,导致程序崩溃或终止。这种错误可能由多种因素引起。 --- #### 可能原因分及其解决办法 1. **数组越界** 数组访问超出其分配的内存范围是最常见的原因之一[^3]。这可能导致不可预测的行为甚至程序崩溃。 - **解决方法**: 阅读题目中的数据范围说明,合理设置数组大小。如果不确定具体数值,可适当增加冗余空间以降低风险。例如: ```cpp int n; cin >> n; vector<int> arr(n + 10); // 多预留一些空间以防万一 ``` 2. **指针操作不当** 如果涉及动态内存管理(如`new`/`delete`),未正确释放资源或将非法地址赋给指针也可能引发RE。 - **解决方法**: 使用现代C++特性(如`std::vector`, `std::unique_ptr`等容器类替代原始指针)。确保每次申请内存后都及时清理不再使用的部分。 3. **除零异常** 当尝试将某个数除以零时会触发此类型的错误。 - **解决方法**: 提前判断分母是否为零再决定如何计算表达式的值。 ```cpp double a = ..., b = ...; if (b != 0){ cout << a / b; }else{ cout << "Error"; } ``` 4. **类型转换失误** 特定情况下某些内置函数对特定的数据类型支持有限制。比如标准库里的`abs()`只适用于较小整型;当遇到更大规模数字则需改用其他版本如`llabs()`针对长整形[^5]。 - **解决方法**: 明确所需运算对象的确切类别并调用相应的适配器完成任务。 5. **栈溢出** 过深递归层次可能会耗尽系统允许的最大堆栈容量从而造成失败退出状况发生。 - **解决方法**: 考虑优化算法结减少不必要的嵌套层数或者切换至迭代形式实现相同功能逻辑。 6. **输入输出格式不符预期** 不按照指定方式获取外部参数亦或是打印结果不符合规定样式同样会被判定存在此类问题。 - **解决方法**: 细致审阅样例测试案例以及提示信息严格遵照指示编写相应代码片段。 7. **第三方依赖缺失** 若项目里引入额外库文件却忘记上传关联源码到评测环境当中也有可能遭遇相似困境。 - **解决方法**: 尽量采用官方文档推荐的基础组件建应用避免过多自定义扩展带来的兼容隐患。 8. **边界条件遗漏考虑** 对极端情况缺乏足够的重视往往成为隐藏漏洞所在之处之一。 - **解决方法**: 设计全面覆盖各类可能性场景单元检验机制验证最终成品质量。 --- ### 总结建议 为了有效预防上述提及的各种潜在陷阱,在日常练习期间应当养成良好习惯如下几点可供参考借鉴: - 认真阅读每一道习题描述材料充分理解需求背景; - 结合实际动手实践不断积累实战经验提升技术水平; - 定期回顾总结过往经历找出薄弱环节加以改进完善; - 积极参与社区交流学习他人优秀做法共同进步成长。 通过持续努力相信能够逐步克服目前面临的困难局面取得理想成绩! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值