STL-vector-size

本文通过几个实例探讨了 C++ 中 vector 的不同初始化方式及其背后的行为差异,特别是使用下标与 push_back 方法的区别。文章揭示了不当使用可能导致的程序崩溃问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Env:

MacBook$ g++ –version
Configured with: –prefix=/Applications/Xcode.app/Contents/Developer/usr –with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix

OS:

Mac OSX 10.9.2

Compile:

-std=c++11

代码:

#include <iostream>
#include <vector>
#include <list>

int main (int argc, char *argv[])
{
    int n = 5;
    std::vector<int> nv(n, -1);
    std::vector<int> nv1, nv2, nv3, nv4, nv5, nv6, nv7;
    nv1.reserve(n);
    nv2.reserve(n);
    nv3.reserve(n);
    nv1[0] = 111;
    nv1[1] = 222;
    std::cout << "nv1 size " << nv1.size() << ", " << "nv1 capacity " << nv1.capacity() << std::endl    ;
    std::cout << "nv1[0] " << nv1[0] << ", " << "nv1[1]" << nv1[1] << std::endl;
    nv2.push_back(111);
    nv2.push_back(222);
    std::cout << "nv2 size " << nv2.size() << ", " << "nv2 capacity " << nv2.capacity() << std::endl    ;
    std::cout << "nv2[0] " << nv2[0] << ", " << "nv2[1]" << nv2[1] << std::endl;
    nv3[0] = 111;
    nv3.push_back(222);
   std::cout << "nv3 size " << nv3.size() << ", " << "nv3 capacity " << nv3.capacity() << std::endl    ;
    std::cout << "nv3[0] " << nv3[0] << ", " << "nv3[1]" << nv3[1] << std::endl;
    nv4.push_back(111);
    std::cout << "nv4 size " << nv4.size() << ", " << "nv4 capacity " << nv4.capacity() << std::endl    ;
    std::cout << "nv4[0] " << nv4[0] << std::endl;
    nv5[0] = 111;
    std::cout << "nv5 size " << nv5.size() << ", " << "nv5 capacity " << nv5.capacity() << std::endl    ;
    std::cout << "nv5[0] " << nv5[0] << std::endl;
    nv6[0] = 111;
    std::cout << "nv6 size " << nv6.size() << ", " << "nv6 capacity " << nv6    .capacity() << std::endl;
    std::cout << "nv6[0] " << nv6[0] << std::endl;
    std::list<int> nl7(n, -1);
    nv7.assign(nl7.begin(), nl7.end());
    std::cout << "nv7 size " << nv7.size() << ", " << "nv7 capacity " << nv7.capacity() << std::endl;
    nv7[0] = 111;
    std::cout << "nv7[0] " << nv7[0] << ", nv7[1]" <<  nv7[1] << std::endl;

    return 0;
}

结果:

nv1 size 0, nv1 capacity 5
nv1[0] 111, nv1[1]222
nv2 size 2, nv2 capacity 5
nv2[0] 111, nv2[1]222
nv3 size 1, nv3 capacity 5
nv3[0] 222, nv3[1]0
nv4 size 1, nv4 capacity 1
nv4[0] 111
Segmentation fault: 11

分析:

nv1 nv2 nv3均使用了 reserve 进行申请空间,所以 capacity 为 5.
nv1 使用下标赋值能够访问赋值成功并正常读取,但是 vector 的 size 并没有更新,所以 size 为 0.
nv2 使用 push_back() 进行赋值,成功并能正常读取,而且 size 也更新了.
nv3 先用下标赋值,赋值成功,显然 size 也没有更新了,后面再用 push_back() 赋值时,把 vector 当成空的来处理,把本来想放到第二个位置的元素值追加到第一个元素的位置了,所以再用下标读取第一个元素的时候是 push_back() 所追加的元素,而第二个元素是系统默认给的值 0.

nv4 nv5 没有申请空间.

nv4 用 push_back() 追加元素的时候,追加成功,能正常读取,并且 size 和 capacity 都为 1,说明 push_back() 申请了空间.

nv5 没有用debug 看细节,应该是赋值的时候就出问题了,目标内存不存在,没办法赋值.

把nv5注释掉,则nv6也是 Segmentation fault: 11

把nv5 nv6 都注释掉,nv7可以输出正常

nv7 size 5, nv7 capacity 5
nv7[0] 111, nv7[1] -1

结论:

看来使用 vector 用下标还是需要多注意 :) :) push_back()适合初始化,另外如果不是定义的时候指定大小,要先 reserve.

vector 两种初始化方法:

1.

std::vector<yourtype> var(numofvalue, intialvalue);

2.

std::vector<yourtype> var;
var.reserve(numofvalue);
for (int i=0; i<numofvalue; i++)
{
    var.push_back(intialvalue);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值