std::vector 中的 Reserve 如何工作 + 使用 [] 访问向量 [英] How reserve in std::vector works + Accessing vector with []

查看:24
本文介绍了std::vector 中的 Reserve 如何工作 + 使用 [] 访问向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 vector[n] = val 在保留空向量之前不会给出分段错误或更改向量数据.检查这个例子:

Why vector[n] = val doesn't give segmentation fault or changes the vector data, right before reserving an empty vector. Check this example:

#include <iostream>
#include <vector>
int main()
{

    std::vector<int> temp;
    temp.reserve(8);

    temp[0] = 1;

    temp[3] = 3; //why no attribution???
    temp[7] = 1;
    temp[8] = 3; //why no segmentation fault???

    std::cout << temp.size();
    for(auto&a: temp){ //because the attribution didn't work, no loop needed
        std::cout << a;
    }


    return 0;   

}

另外,为什么操作符 [] 不会抛出 'out_of_range',因为如果使用它代替方法 .at()

Also, why the operator [] doesn't throw 'out_of_range', as the program would if it was used instead the method .at()

推荐答案

您正在通过访问不应该访问的内存来创建未定义的行为.不幸的是,内存仍然分配给您的程序,因此操作系统不会杀死您的程序.

You are creating undefined behavior by accessing memory that you should not. Unfortunately, the memory is still allocated to your program, therefore the operating system does not kill your program.

要查看您做错了什么,请像这样编译您的程序:

To see that you are doing something wrong, compile your program like so:

g++ test.cpp -fsanitize=address

当你现在运行它时,它会非常清楚地告诉你你正在做一些你不应该做的事情:

When you now run it, it will tell you pretty clearly that you are doing something you should not:

=================================================================                                                      
==17401==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000030 at pc 0x000000401208 bp 0x7ffee64f71f0 sp 0x7ffee64f71e0                                                                                                     
WRITE of size 4 at 0x603000000030 thread T0                                                                            
    #0 0x401207 in main /home/mu/test.cpp:13                                                                           
    #1 0x7fbcba273889 in __libc_start_main (/lib64/libc.so.6+0x20889)                                                  
    #2 0x400f49 in _start (/home/mu/a.out+0x400f49)                                                                    

0x603000000030 is located 0 bytes to the right of 32-byte region [0x603000000010,0x603000000030)                       
allocated by thread T0 here:                                                                                           
    #0 0x7fbcbafbe158 in operator new(unsigned long) (/lib64/libasan.so.4+0xe0158)                                     
    #1 0x4022d6 in __gnu_cxx::new_allocator<int>::allocate(unsigned long, void const*) /usr/include/c++/7/ext/new_allocator.h:111                                                                                                             
    #2 0x40222d in std::allocator_traits<std::allocator<int> >::allocate(std::allocator<int>&, unsigned long) /usr/include/c++/7/bits/alloc_traits.h:436                                                                                      
    #3 0x402153 in std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long) /usr/include/c++/7/bits/stl_vector.h:172                                                                                                          
    #4 0x401ebb in int* std::vector<int, std::allocator<int> >::_M_allocate_and_copy<std::move_iterator<int*> >(unsigned long, std::move_iterator<int*>, std::move_iterator<int*>) /usr/include/c++/7/bits/stl_vector.h:1260                  
    #5 0x401671 in std::vector<int, std::allocator<int> >::reserve(unsigned long) /usr/include/c++/7/bits/vector.tcc:73
    #6 0x4010c9 in main /home/mu/test.cpp:7                                                                            
    #7 0x7fbcba273889 in __libc_start_main (/lib64/libc.so.6+0x20889)                                                  

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/mu/test.cpp:13 in main
Shadow bytes around the buggy address:
  0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c067fff8000: fa fa 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa
  0x0c067fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==17401==ABORTING

这篇关于std::vector 中的 Reserve 如何工作 + 使用 [] 访问向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆