valgrind 中函数指针的读取大小无效
Invalid read size with function pointers in valgrind
我一直遇到一个相当复杂的应用程序问题,其中 valgrind 报告与使用函数指针相关的无效读取大小问题。我试图将问题减少到尽可能小的代码。基本上,有一个 class A
定义了一个函数 model
,它将一些数据作为参数。 Class B
具有函数指针,稍后设置为 class A
实例的 model
函数。函数B->run()
然后调用函数指针。
#include <iostream>
#include <vector>
#include <functional>
using namespace std::placeholders;
class A
{
public:
A() {};
~A(){};
void model(std::vector<double>*);
};
void A::model(std::vector<double>* data)
{
for (size_t i = 0; i <= (*data).size(); ++i) {
std::cout << (*data)[i] << std::endl;
}
return;
}
class B
{
public:
B() {};
~B(){};
void run();
std::function<void(std::vector<double>*)> f_model;
};
void B::run()
{
std::vector<double> data(10, 1);
f_model(&data);
return;
}
int main(int argc, char** argv)
{
A* a = new A();
B* b = new B();
b->f_model = std::bind(&A::model, a, _1);
b->run();
delete b;
delete a;
exit(EXIT_SUCCESS);
}
运行 在 valgrind 下我收到消息
==21841== Invalid read of size 8
==21841== at 0x400C9B: A::model(std::vector<double, std::allocator<double> >*) (in /home/code/snippets/cpptest/main)
==21841== by 0x40233D: void std::_Mem_fn<void (A::*)(std::vector<double, std::allocator<double> >*)>::operator()<std::vector<double, std::allocator<double> >*, void>(A*, std::vector<double, std::allocator<double> >*&&) const (in /home/code/snippets/cpptest/main)
==21841== by 0x4021F0: void std::_Bind<std::_Mem_fn<void (A::*)(std::vector<double, std::allocator<double> >*)> (A*, std::_Placeholder<1>)>::__call<void, std::vector<double, std::allocator<double> >*&&, 0ul, 1ul>(std::tuple<std::vector<double, std::allocator<double> >*&&>&&, std::_Index_tuple<0ul, 1ul>) (in /home/code/snippets/cpptest/main)
==21841== by 0x401EB0: void std::_Bind<std::_Mem_fn<void (A::*)(std::vector<double, std::allocator<double> >*)> (A*, std::_Placeholder<1>)>::operator()<std::vector<double, std::allocator<double> >*, void>(std::vector<double, std::allocator<double> >*&&) (in /home/code/snippets/cpptest/main)
==21841== by 0x401B3C: std::_Function_handler<void (std::vector<double, std::allocator<double> >*), std::_Bind<std::_Mem_fn<void (A::*)(std::vector<double, std::allocator<double> >*)> (A*, std::_Placeholder<1>)> >::_M_invoke(std::_Any_data const&, std::vector<double, std::allocator<double> >*) (in /home/code/snippets/cpptest/main)
==21841== by 0x401152: std::function<void (std::vector<double, std::allocator<double> >*)>::operator()(std::vector<double, std::allocator<double> >*) const (in /home/code/snippets/cpptest/main)
==21841== by 0x400D3C: B::run() (in /home/code/snippets/cpptest/main)
==21841== by 0x400E18: main (in /home/code/snippets/cpptest/main)
==21841== Address 0x5a1c1a0 is 0 bytes after a block of size 80 alloc'd
==21841== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21841== by 0x401FBF: __gnu_cxx::new_allocator<double>::allocate(unsigned long, void const*) (in /home/code/snippets/cpptest/main)
==21841== by 0x401D8E: std::_Vector_base<double, std::allocator<double> >::_M_allocate(unsigned long) (in /home/code/snippets/cpptest/main)
==21841== by 0x40199E: std::_Vector_base<double, std::allocator<double> >::_M_create_storage(unsigned long) (in /home/code/snippets/cpptest/main)
==21841== by 0x401306: std::_Vector_base<double, std::allocator<double> >::_Vector_base(unsigned long, std::allocator<double> const&) (in /home/code/snippets/cpptest/main)
==21841== by 0x40107D: std::vector<double, std::allocator<double> >::vector(unsigned long, double const&, std::allocator<double> const&) (in /home/code/snippets/cpptest/main)
==21841== by 0x400D1D: B::run() (in /home/code/snippets/cpptest/main)
==21841== by 0x400E18: main (in /home/code/snippets/cpptest/main)
==21841==
0
==21841==
==21841== HEAP SUMMARY:
==21841== in use at exit: 0 bytes in 0 blocks
==21841== total heap usage: 4 allocs, 4 frees, 137 bytes allocated
==21841==
==21841== All heap blocks were freed -- no leaks are possible
我很难理解为什么会出现这种无效的读取大小,但我想摆脱它。有什么想法吗?
问题与函数指针无关。错误在这里:
for (size_t i = 0; i <= (*data).size(); ++i) {
std::cout << (*data)[i] << std::endl;
}
您正在阅读 (*data).size()+1
个元素,即从 0 到 (*data).size()
(含)。在您的情况下,这是十个元素中的 11 个元素 std::vector
.
将 <=
替换为 <
或 !=
将修复无效读取:
for (size_t i = 0; i != (*data).size(); ++i) {
std::cout << (*data)[i] << std::endl;
}
我一直遇到一个相当复杂的应用程序问题,其中 valgrind 报告与使用函数指针相关的无效读取大小问题。我试图将问题减少到尽可能小的代码。基本上,有一个 class A
定义了一个函数 model
,它将一些数据作为参数。 Class B
具有函数指针,稍后设置为 class A
实例的 model
函数。函数B->run()
然后调用函数指针。
#include <iostream>
#include <vector>
#include <functional>
using namespace std::placeholders;
class A
{
public:
A() {};
~A(){};
void model(std::vector<double>*);
};
void A::model(std::vector<double>* data)
{
for (size_t i = 0; i <= (*data).size(); ++i) {
std::cout << (*data)[i] << std::endl;
}
return;
}
class B
{
public:
B() {};
~B(){};
void run();
std::function<void(std::vector<double>*)> f_model;
};
void B::run()
{
std::vector<double> data(10, 1);
f_model(&data);
return;
}
int main(int argc, char** argv)
{
A* a = new A();
B* b = new B();
b->f_model = std::bind(&A::model, a, _1);
b->run();
delete b;
delete a;
exit(EXIT_SUCCESS);
}
运行 在 valgrind 下我收到消息
==21841== Invalid read of size 8
==21841== at 0x400C9B: A::model(std::vector<double, std::allocator<double> >*) (in /home/code/snippets/cpptest/main)
==21841== by 0x40233D: void std::_Mem_fn<void (A::*)(std::vector<double, std::allocator<double> >*)>::operator()<std::vector<double, std::allocator<double> >*, void>(A*, std::vector<double, std::allocator<double> >*&&) const (in /home/code/snippets/cpptest/main)
==21841== by 0x4021F0: void std::_Bind<std::_Mem_fn<void (A::*)(std::vector<double, std::allocator<double> >*)> (A*, std::_Placeholder<1>)>::__call<void, std::vector<double, std::allocator<double> >*&&, 0ul, 1ul>(std::tuple<std::vector<double, std::allocator<double> >*&&>&&, std::_Index_tuple<0ul, 1ul>) (in /home/code/snippets/cpptest/main)
==21841== by 0x401EB0: void std::_Bind<std::_Mem_fn<void (A::*)(std::vector<double, std::allocator<double> >*)> (A*, std::_Placeholder<1>)>::operator()<std::vector<double, std::allocator<double> >*, void>(std::vector<double, std::allocator<double> >*&&) (in /home/code/snippets/cpptest/main)
==21841== by 0x401B3C: std::_Function_handler<void (std::vector<double, std::allocator<double> >*), std::_Bind<std::_Mem_fn<void (A::*)(std::vector<double, std::allocator<double> >*)> (A*, std::_Placeholder<1>)> >::_M_invoke(std::_Any_data const&, std::vector<double, std::allocator<double> >*) (in /home/code/snippets/cpptest/main)
==21841== by 0x401152: std::function<void (std::vector<double, std::allocator<double> >*)>::operator()(std::vector<double, std::allocator<double> >*) const (in /home/code/snippets/cpptest/main)
==21841== by 0x400D3C: B::run() (in /home/code/snippets/cpptest/main)
==21841== by 0x400E18: main (in /home/code/snippets/cpptest/main)
==21841== Address 0x5a1c1a0 is 0 bytes after a block of size 80 alloc'd
==21841== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21841== by 0x401FBF: __gnu_cxx::new_allocator<double>::allocate(unsigned long, void const*) (in /home/code/snippets/cpptest/main)
==21841== by 0x401D8E: std::_Vector_base<double, std::allocator<double> >::_M_allocate(unsigned long) (in /home/code/snippets/cpptest/main)
==21841== by 0x40199E: std::_Vector_base<double, std::allocator<double> >::_M_create_storage(unsigned long) (in /home/code/snippets/cpptest/main)
==21841== by 0x401306: std::_Vector_base<double, std::allocator<double> >::_Vector_base(unsigned long, std::allocator<double> const&) (in /home/code/snippets/cpptest/main)
==21841== by 0x40107D: std::vector<double, std::allocator<double> >::vector(unsigned long, double const&, std::allocator<double> const&) (in /home/code/snippets/cpptest/main)
==21841== by 0x400D1D: B::run() (in /home/code/snippets/cpptest/main)
==21841== by 0x400E18: main (in /home/code/snippets/cpptest/main)
==21841==
0
==21841==
==21841== HEAP SUMMARY:
==21841== in use at exit: 0 bytes in 0 blocks
==21841== total heap usage: 4 allocs, 4 frees, 137 bytes allocated
==21841==
==21841== All heap blocks were freed -- no leaks are possible
我很难理解为什么会出现这种无效的读取大小,但我想摆脱它。有什么想法吗?
问题与函数指针无关。错误在这里:
for (size_t i = 0; i <= (*data).size(); ++i) {
std::cout << (*data)[i] << std::endl;
}
您正在阅读 (*data).size()+1
个元素,即从 0 到 (*data).size()
(含)。在您的情况下,这是十个元素中的 11 个元素 std::vector
.
将 <=
替换为 <
或 !=
将修复无效读取:
for (size_t i = 0; i != (*data).size(); ++i) {
std::cout << (*data)[i] << std::endl;
}