Boost图Bundled Properties使用报错:const属性映射赋值失败原因
这个错误的根源其实和你最后一行修改taxon属性的代码无关,而是出在你提前获取edge_weight property map的操作上!
为什么会报错?
你在代码里先创建了空的Graph g,然后立刻获取了edge_weight的property map:
boost::property_map<Graph, boost::edge_weight_t>::type weight = get(boost::edge_weight,g);
之后你把这个weight对象传入dynamic_properties,用来处理dot文件里的time边属性。但是boost::read_graphviz在读取图的时候,会先清空当前图的所有顶点和边,然后重新根据dot文件的内容构建整个图。这就导致你之前获取的weight property map已经失效了——它关联的是旧的、已经被销毁的图数据。
当read_graphviz尝试向这个失效的map写入边的time属性时,内存访问出现异常,错误信息被误导性地显示为“Attempt to put a value into a const property map”,但本质是内存损坏问题。
修复步骤
只需要把提前获取weight map的代码去掉,直接在dp.property调用中动态获取当前图的edge_weight map即可:
修改前:
boost::property_map<Graph, boost::edge_weight_t>::type weight = get(boost::edge_weight,g); dp.property("time", weight);
修改后:
dp.property("time", get(boost::edge_weight, g));
这样read_graphviz使用的始终是当前图的有效property map,不会出现失效问题。
验证修改顶点属性的代码
修复上述问题后,你最后一行的g[1].taxon = blah就可以正常工作了——因为你的图使用vecS作为顶点容器,顶点索引是连续的,读取dot文件后顶点1确实存在,直接访问bundled property的成员变量是合法的。
如果你更喜欢用property map的方式修改属性(更符合Boost Graph Library的风格),也可以这样写:
auto taxon_map = get(&Vertex::taxon, g); put(taxon_map, 1, blah);
内容的提问来源于stack exchange,提问作者Sailanarmo

