我正在使用Boost.Graph库通过Bellman-Ford算法找到图中的最短路径。但是,我的程序在执行中被杀死。
我准备了一段代码:
typedef boost::property<boost::edge_weight_t, double > Weight;
typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::directedS, boost::no_property, Weight > DirectedGraph;
DirectedGraph g;
std::vector<Node> list;
for(int i = 0; i < 100; i++)
{
list.push_back(Node(rand() % 100)); // getValue() will return this value
}
std::vector<std::pair<Order, DirectedGraph::vertex_descriptor>> values;
for(auto v : list)
{
values.push_back(std::pair<Node, DirectedGraph::vertex_descriptor>(v, boost::add_vertex(g)));
}
for(auto v : values)
{
for(auto u : values)
{
if(v == u)
continue;
else if(/* some conditions are met*/)
boost::add_edge(v.second, u.second, -std::log(u.first.getValue()), g);
}
}
boost::property_map<DirectedGraph, boost::edge_weight_t>::type weight_pmap = get(boost::edge_weight_t(), g);
unsigned int nb_vertices = boost::num_vertices(g);
for(auto v : values)
{
if(/* v meets conditions to be a source vertex*/)
{
int entry_point = v.second;
std::vector<double> distance(nb_vertices, (std::numeric_limits < double >::max)());
distance[entry_point] = 0;
std::vector<std::size_t> parent(nb_vertices);
for (unsigned int i = 0; i < nb_vertices; i++)
parent[i] = i;
bool r = boost::bellman_ford_shortest_paths(
g,
nb_vertices,
weight_map(weight_pmap).
distance_map(&distance[entry_point]).
predecessor_map(&parent[entry_point])
);
}
}
我对official example略有变化进行了编程。
正如我所说,程序在执行中被杀死了。我使用 gdb 和 valgrind 来获取更详细的错误消息:
GDB :
Error in ...: double free or corruption (out): 0x0000000000cdadb0
Program received signal SIGABRT, Aborted.
0x00007ffff5abdcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: File or Directory not found
(gdb) where
#0 0x00007ffff5abdcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007ffff5ac10d8 in __GI_abort () at abort.c:89
#2 0x00007ffff5afa394 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7ffff5c08b28 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3 0x00007ffff5b0666e in malloc_printerr (ptr=<optimized out>, str=0x7ffff5c08c58 "double free or corruption (out)", action=1) at malloc.c:4996
#4 _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3840
#5 0x000000000055297e in __gnu_cxx::new_allocator<unsigned long>::deallocate (this=0x7fffffffd010, __p=0xcdadb0) at /usr/include/c++/4.8/ext/new_allocator.h:110
#6 0x0000000000550d5c in std::_Vector_base<unsigned long, std::allocator<unsigned long> >::_M_deallocate (this=0x7fffffffd010, __p=0xcdadb0, __n=14) at /usr/include/c++/4.8/bits/stl_vector.h:174
#7 0x000000000054eea1 in std::_Vector_base<unsigned long, std::allocator<unsigned long> >::~_Vector_base (this=0x7fffffffd010, __in_chrg=<optimized out>) at /usr/include/c++/4.8/bits/stl_vector.h:160
#8 0x000000000054db67 in std::vector<unsigned long, std::allocator<unsigned long> >::~vector (this=0x7fffffffd010, __in_chrg=<optimized out>) at /usr/include/c++/4.8/bits/stl_vector.h:416
#9 0x000000000054a32e in OrderList::makePaths () at ../BetherV2/Global/OrderList/orderlist.cpp:343
#10 0x00000000004b1e16 in main () at ../BetherV2/main.cpp:33
Valgrind的:
==5476== Invalid read of size 8
==5476== at 0x55452E: bool boost::relax<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, double, boost::no_property>, boost::n$
==5476== by 0x552CE3: bool boost::bellman_ford_shortest_paths<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, double, boost::$
==5476== by 0x550F4F: bool boost::detail::bellman_dispatch2<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, double, boost::no$
==5476== by 0x54F0D0: bool boost::detail::bellman_dispatch<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, double, boost::no_$
==5476== by 0x54DC91: bool boost::bellman_ford_shortest_paths<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, double, boost::$
==5476== by 0x54A318: OrderList::makePaths() (orderlist.cpp:354)
==5476== by 0x4B1E15: main (main.cpp:33)
==5476== Address 0x1e313340 is 0 bytes after a block of size 112 alloc'd
==5476== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5476== by 0x553C9D: __gnu_cxx::new_allocator<double>::allocate(unsigned long, void const*) (new_allocator.h:104)
==5476== by 0x552898: std::_Vector_base<double, std::allocator<double> >::_M_allocate(unsigned long) (in /home/alex/C++/build-BetherV2-Desktop-Debug/BetherV2)
==5476== by 0x550BCE: std::_Vector_base<double, std::allocator<double> >::_M_create_storage(unsigned long) (stl_vector.h:181)
==5476== by 0x54ECDC: std::_Vector_base<double, std::allocator<double> >::_Vector_base(unsigned long, std::allocator<double> const&) (stl_vector.h:136)
==5476== by 0x54D9F1: std::vector<double, std::allocator<double> >::vector(unsigned long, double const&, std::allocator<double> const&) (stl_vector.h:283)
==5476== by 0x54A1A5: OrderList::makePaths() (orderlist.cpp:340)
==5476== by 0x4B1E15: main (main.cpp:33)
--5476-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--5476-- si_code=1; Faulting address: 0x9; sp: 0x802f9ddd0
valgrind: the 'impossible' happened:
Killed by fatal signal
在 gdb 错误中,“orderlist.cpp:343”引用std::vector<std::size_t> parent(nb_vertices);
在 valgrind 错误中,“orderlist.cpp:340”引用std::vector<double> distance(nb_vertices, (std::numeric_limits < double >::max)());
我试图解决这个问题,因为昨天我找不到问题的根源。似乎Bellman-Ford算法试图访问其边界之外的距离/父图。但为什么会这样呢?