Boost属性树:将值读入char *

时间:2014-05-23 19:28:48

标签: c++ boost char boost-propertytree

我正在阅读ptree的各种数据。其中一个字段声明为

char * segmentCode;

所以我以这种方式读取segmentCode:

segmentCode = dataTree.get<char*>("segmentCode");

但是,它会引发访问冲突。我哪里做错了?

解决方法很难看:

string tmpStr = dataTree.get<string>("segmentCode");    
segmentCode = strdup(tmpStr.c_str());

1 个答案:

答案 0 :(得分:3)

使用char *作为segmentCode的原因是什么?在C ++世界中,首选是使用其他对象来管理相关数据(例如,std :: string,std :: vector&lt;&gt;)

如果我们查看ptree.hpp标题:

/**
  * A property tree with std::string for key and data, and default
  * comparison.
  */
typedef basic_ptree<std::string, std::string> ptree;

我们可以看到ptree在内部使用std :: string作为其键和值。这意味着ptree的首选数据格式是std :: string。

因此建议使用:

std::string segmentCode = dataTree.get<std::string>("segmentCode");

这比您的解决方法更有效,因为字符串只应被复制一次(来自ptree)。虽然strdup将创建另一个副本,然后需要稍后显式调用free

-

现在关于访问违规的来源......

如果我们看一下basic_tree::get<Type>()方法:

/** Shorthand for get_child(path).get_value\<Type\>(). */
template<class Type>
Type get(const path_type &path) const;

我们看到此调用basic_tree::get_value<Type>()

/** Take the value of this node and attempt to translate it to a
 * @c Type object using the default translator.
 * @throw ptree_bad_data if the conversion fails.
 */
template<class Type>
Type get_value() const;

请注意提及类型转换和默认翻译。

在调用堆栈的下方,我们发现访问冲突点实际上在转换过程中,可以在stream_translator.hpp(customize_stream :: extract)中找到:

static void extract(std::basic_istream<Ch, Traits>& s, E& e) {
    s >> e;
    if(!s.eof()) {
        s >> std::ws;
    }
}

以这种方式使用流是在类型之间进行一般转换的常用技术。特别是当转换为/来自的类型之一是字符串时。

这里的问题是get<char*>定义了存储类型(我们将值放在哪里)作为char指针。从ptree的角度来看,这被认为是一个可以保存值的完整类型,而转换流将其视为指向可以写入的内存区域的指针。

这相当于:

std::istringstream iss("value");
char * p; // uninitialized pointer
iss >> p; // write to some random memory location

是发生访问冲突的原因。

再次传递给get<Type> Type 应该能够保存完整的值。