Valgrind错误解引用std::vector返回的地址

为什么valgrind会为这段代码返回错误?

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> vec;
    int *ptr;

    for (int i = 0; i < 1000; i++)
    {
        vec.push_back(i);
        if (i == 100)
        {
            ptr = &vec[i];
        }
    }
    std::cout << ptr << "n";  // Print address of -> Ok
    std::cout << *ptr << "n"; // Print content of -> Ok but with a valgrind error
}

编译: g++ -Wall -Wpedantic -O0 -o demo demo.cpp

valgrind 错误是:

==3982== Invalid read of size 4
==3982==    at 0x1093A7: main (in /home/david/demo)
==3982==  Address 0x4dae1e0 is 400 bytes inside a block of size 512 free'd
==3982==    at 0x483E1CF: operator delete(void*, unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==3982==    by 0x109EB4: __gnu_cxx::new_allocator<int>::deallocate(int*, unsigned long) (in /home/david/demo)
==3982==    by 0x109B5B: std::allocator_traits<std::allocator<int> >::deallocate(std::allocator<int>&, int*, unsigned long) (in /home/david/demo)
==3982==    by 0x10970F: std::_Vector_base<int, std::allocator<int> >::_M_deallocate(int*, unsigned long) (in /home/david/demo)
==3982==    by 0x109A3B: void std::vector<int, std::allocator<int> >::_M_realloc_insert<int const&>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const&) (in /home/david/demo)
==3982==    by 0x10964F: std::vector<int, std::allocator<int> >::push_back(int const&) (in /home/david/demo)
==3982==    by 0x109354: main (in /home/david/demo)
==3982==  Block was alloc'd at
==3982==    at 0x483CE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==3982==    by 0x10A0FF: __gnu_cxx::new_allocator<int>::allocate(unsigned long, void const*) (in /home/david/demo)
==3982==    by 0x109F73: std::allocator_traits<std::allocator<int> >::allocate(std::allocator<int>&, unsigned long) (in /home/david/demo)
==3982==    by 0x109DAD: std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long) (in /home/david/demo)
==3982==    by 0x1098BC: void std::vector<int, std::allocator<int> >::_M_realloc_insert<int const&>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const&) (in /home/david/demo)
==3982==    by 0x10964F: std::vector<int, std::allocator<int> >::push_back(int const&) (in /home/david/demo)
==3982==    by 0x109354: main (in /home/david/demo)
==3982== 

这让我怀疑取消引用向量返回的地址是否具有未定义的行为,这是合法的代码吗?

回答

Valgrind 说这是“无效读取”。在push_back操作期间,std::vector如果需要,将重新分配内存并将所有数据复制到新位置。

如果是这样,您可能ptr指向的是不再分配给 vector 的内存vec

所以是的,它可能是你使用它的方式。

reserve如果您已经知道要插入的元素数量,最好先内存,然后简单地将元素插入正确的位置。

  • Actually, I think it only *might* be UB. An implementation could have allocated enough memory so that no reallocation is done after the address of an element is taken.

以上是Valgrind错误解引用std::vector返回的地址的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>