再学C++ | STL库中可能存在的内存溢出与脏数据问题

STL库中的 vector 是我们使用最频繁的STD容器之一。它具有广泛的应用,并且在性能方面表现出色。然而,其存在一种潜在问题,即溢出。由于 vector 在使用下标访问元素时不会检查索引是否越界,因此很可能导致溢出错误的出现。这种错误被严格定义为一种内存的"dirty read / dirty write"

下面的代码就是模拟这样的一种情况:
首先在内存中声明一个长度为 16 的 vector 并命名为 tmp,用来在内存中写入藏数据。然后紧跟着声明一个长度为 16 的全 0 vector 。这里构建一个名为 dirty_write 的函数,其中向随机产生的索引中写入值,因为这里产生的索引不一定在 16 以内,所以会随机写入脏数据。

#include <iostream>
using namespace std;

void dirty_write(std::vector<double> &args) {
    int r = rand() % 40 - 10;
    args[r] = rand() % 101 - 50;
}

int main() {
    vector<double> tmp(16);
    vector<double> zero_vec(16, 0);
    cout << "Before: " << endl;
    for (int i = 0; i < zero_vec.size(); ++i) {
        cout << zero_vec[i] << " ";
    }
    for (int i = 0; i < 10000; i++) {
        dirty_write(tmp);
    }
    cout << "\nAfter: " << endl;
    for (int i = 0; i < zero_vec.size(); ++i) {
        cout << zero_vec[i] << " ";
    }
    return 0;
}

上面的代码中的 zero_vec 初始化一个长度为 16 的全 0 数组,但实际运行结果是是这样的:

运行结果

经过查询发现STL中有在运行中检查index "__n" 是否在范围内的代码,并通过_LIBCPP_DEBUG 控制,默认时 _LIBCPP_DEBUG 被设置为 0 检查 assert 不开启,但是可以在编译时手动开启这个技能,即在g++ 编译时加上如下参数:

g++ -D_LIBCPP_DEBUG=1 ...

参考:才哥第十四讲 std:set (二)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值