vector::data() 指针使用细节

我们可以使用std::vector<T>::data() 返回的指针做内存操作,但需要一些细节。比如

#include<iostream>
#include<iterator>
#include<vector>

int main(int argc, char **argv)
{
    std::vector<int> dss;
    dss.reserve(2);
    int eeee[2]{11, 22};
    ::memcpy(dss.data(), eeee, sizeof(eeee));
    std::copy(dss.begin(), dss.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;

    return 0;
}

测试一下,你会发现没有任何输出。

原因是memcpy是纯内存拷贝,数据其实已经拷贝进去了,但是vector的size并没有因为我们拷贝做合适的调整,所以我们访问vector的时候是一个empty(),是访问不到的。改成如下

#include<iostream>
#include<iterator>
#include<vector>

int main(int argc, char **argv)
{
    std::vector<int> dss;
    dss.reserve(2);
    int eeee[2]{11, 22};
    ::memcpy(dss.data(), eeee, sizeof(eeee));
    std::copy(dss.begin(), dss.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;

    auto p = dss.data();
    for (int i = 0; i < sizeof(eeee) / sizeof(int); i++)
    {
        std::cout << p[i] << " ";
    }
    std::cout << std::endl;
    return 0;
}

        此时你会发现有数据了,证实了数据是真的拷贝进去了的。找清原因后,我们也可以使用vector::resize函数来初始化空间,同时更改vector的可访问size大小

#include<iostream>
#include<iterator>
#include<vector>

int main(int argc, char **argv)
{
    std::vector<int> dss;
    dss.resize(2);
    int eeee[2]{11, 22};
    ::memcpy(dss.data(), eeee, sizeof(eeee));
    std::copy(dss.begin(), dss.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;


    return 0;
}

        这样也有输出了。

        需要提醒的是,下面这样是不行的

#include<iostream>
#include<iterator>
#include<vector>

int main(int argc, char **argv)
{
    std::vector<int> dss;
    dss.reserve(2);
    int eeee[2]{11, 22};
    ::memcpy(dss.data(), eeee, sizeof(eeee));
    dss.resize(2);
    std::copy(dss.begin(), dss.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;


    return 0;
}

        此处,先开空间,然后拷贝,再修改大小,看似行得通,其实不然。先开空间2个int,然后拷贝;再resize时,由于此时vector的size仍是0(拷贝数据并没有修改其size),调用时空间大小是2,不会重新分配空间,但是目前size是0,会从0开始默认填充2个0做为默认元素,此时size也变成了2。这个用例你会发现输出结果全是0。

        总结,使用刚初始化的vector的data()返回指针,向其拷贝数据的时候,必须先保证其空间和size大小,调用resize即可;也可以先调用reserve,再调用push_back,这个就不是操作指针拷贝了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值