C++ 如何在stxxl::map中使用std::string作为键
我试图使用std::string作为stxxl::map中的键 对于少量的字符串(大约10-100个),插入效果很好。 但是,当我试图在其中插入大量大约100000个字符串时,我遇到了分段错误 代码如下:C++ 如何在stxxl::map中使用std::string作为键,c++,string,map,stxxl,C++,String,Map,Stxxl,我试图使用std::string作为stxxl::map中的键 对于少量的字符串(大约10-100个),插入效果很好。 但是,当我试图在其中插入大量大约100000个字符串时,我遇到了分段错误 代码如下: struct CompareGreaterString { bool operator () (const std::string& a, const std::string& b) const { return a > b; } s
struct CompareGreaterString {
bool operator () (const std::string& a, const std::string& b) const {
return a > b;
}
static std::string max_value() {
return "";
}
};
// template parameter <KeyType, DataType, CompareType, RawNodeSize, RawLeafSize, PDAllocStrategy (optional)>
typedef stxxl::map<std::string, unsigned int, CompareGreaterString, DATA_NODE_BLOCK_SIZE, DATA_LEAF_BLOCK_SIZE> name_map;
name_map strMap((name_map::node_block_type::raw_size)*3, (name_map::leaf_block_type::raw_size)*3);
for (unsigned int i = 0; i < 1000000; i++) { /// Inserting 1 million strings
std::stringstream strStream;
strStream << (i);
Console::println("Inserting: " + strStream.str());
strMap[strStream.str()]=i;
}
static const int MAX_KEY_LEN = 16;
class FixedString {
public:
char charStr[MAX_KEY_LEN];
bool operator< (const FixedString& fixedString) const {
return std::lexicographical_compare(charStr, charStr+MAX_KEY_LEN,
fixedString.charStr, fixedString.charStr+MAX_KEY_LEN);
}
bool operator==(const FixedString& fixedString) const {
return std::equal(charStr, charStr+MAX_KEY_LEN, fixedString.charStr);
}
bool operator!=(const FixedString& fixedString) const {
return !std::equal(charStr, charStr+MAX_KEY_LEN, fixedString.charStr);
}
};
struct comp_type : public std::less<FixedString> {
static FixedString max_value()
{
FixedString s;
std::fill(s.charStr, s.charStr+MAX_KEY_LEN, 0x7f);
return s;
}
};
typedef stxxl::map<FixedString, unsigned int, comp_type, DATA_NODE_BLOCK_SIZE, DATA_LEAF_BLOCK_SIZE> fixed_name_map;
fixed_name_map myFixedMap((fixed_name_map::node_block_type::raw_size)*5, (fixed_name_map::leaf_block_type::raw_size)*5);
struct CompareGreaterString{
布尔运算符()(常量std::string&a,常量std::string&b)常量{
返回a>b;
}
静态标准::字符串最大值(){
返回“”;
}
};
//模板参数
typedef stxxl::map name_map;
名称映射标准映射((名称映射::节点块类型::原始大小)*3,(名称映射::叶块类型::原始大小)*3);
对于(无符号整数i=0;i<1000000;i++){///插入一百万个字符串
std::stringstream stream;
strStream根据:
CompareType还必须提供一个静态最大值方法,该方法返回的KeyType类型的值大于map中存储的任何键
因为空字符串恰好比任何其他字符串都小,所以它会破坏此前提条件,从而可能导致未指定的行为
这里有一个应该可以使用的max\u值
。max\u KEY\u LEN
只是一个整数,它大于或等于映射可能具有的最长字符串键的长度
struct CompareGreaterString {
// ...
static std::string max_value() {
return std::string(MAX_KEY_LEN, std::numeric_limits<unsigned char>::max());
}
};
struct CompareGreaterString{
// ...
静态标准::字符串最大值(){
返回std::string(MAX_KEY_LEN,std::numeric_limits::MAX());
}
};
根据:
CompareType还必须提供一个静态最大值方法,该方法返回的KeyType类型的值大于map中存储的任何键
因为空字符串恰好比任何其他字符串都小,所以它会破坏此前提条件,从而可能导致未指定的行为
这里有一个应该可以使用的max\u值
。max\u KEY\u LEN
只是一个整数,它大于或等于映射可能具有的最长字符串键的长度
struct CompareGreaterString {
// ...
static std::string max_value() {
return std::string(MAX_KEY_LEN, std::numeric_limits<unsigned char>::max());
}
};
struct CompareGreaterString{
// ...
静态标准::字符串最大值(){
返回std::string(MAX_KEY_LEN,std::numeric_limits::MAX());
}
};
在Timo bingmann、user2079303和Martin Ba的大力帮助下,我终于找到了问题的解决方案。谢谢
我想和你分享一下
首先,stxxl只支持POD。这意味着它只存储固定大小的结构。因此std::string不能是键。stxxl::map用于大约100-1000个字符串,因为它们包含在物理内存中。当插入更多字符串时,它必须在磁盘上写入,这在内部造成了一些问题
因此,我们需要使用char[]的固定字符串,如下所示:
struct CompareGreaterString {
bool operator () (const std::string& a, const std::string& b) const {
return a > b;
}
static std::string max_value() {
return "";
}
};
// template parameter <KeyType, DataType, CompareType, RawNodeSize, RawLeafSize, PDAllocStrategy (optional)>
typedef stxxl::map<std::string, unsigned int, CompareGreaterString, DATA_NODE_BLOCK_SIZE, DATA_LEAF_BLOCK_SIZE> name_map;
name_map strMap((name_map::node_block_type::raw_size)*3, (name_map::leaf_block_type::raw_size)*3);
for (unsigned int i = 0; i < 1000000; i++) { /// Inserting 1 million strings
std::stringstream strStream;
strStream << (i);
Console::println("Inserting: " + strStream.str());
strMap[strStream.str()]=i;
}
static const int MAX_KEY_LEN = 16;
class FixedString {
public:
char charStr[MAX_KEY_LEN];
bool operator< (const FixedString& fixedString) const {
return std::lexicographical_compare(charStr, charStr+MAX_KEY_LEN,
fixedString.charStr, fixedString.charStr+MAX_KEY_LEN);
}
bool operator==(const FixedString& fixedString) const {
return std::equal(charStr, charStr+MAX_KEY_LEN, fixedString.charStr);
}
bool operator!=(const FixedString& fixedString) const {
return !std::equal(charStr, charStr+MAX_KEY_LEN, fixedString.charStr);
}
};
struct comp_type : public std::less<FixedString> {
static FixedString max_value()
{
FixedString s;
std::fill(s.charStr, s.charStr+MAX_KEY_LEN, 0x7f);
return s;
}
};
typedef stxxl::map<FixedString, unsigned int, comp_type, DATA_NODE_BLOCK_SIZE, DATA_LEAF_BLOCK_SIZE> fixed_name_map;
fixed_name_map myFixedMap((fixed_name_map::node_block_type::raw_size)*5, (fixed_name_map::leaf_block_type::raw_size)*5);
static const int MAX_KEY_LEN=16;
类FixedString{
公众:
char charStr[MAX_KEY_LEN];
布尔运算符<(常量固定字符串和固定字符串)常量{
return std::lexicographic_compare(charStr,charStr+MAX_KEY_LEN,
fixedString.charStr,fixedString.charStr+MAX\u KEY\u LEN);
}
布尔运算符==(常量FixedString和FixedString)常量{
返回std::equal(charStr,charStr+MAX_KEY_LEN,fixedString.charStr);
}
布尔运算符!=(常量固定字符串和固定字符串)常量{
return!std::equal(charStr,charStr+MAX_KEY_LEN,fixedString.charStr);
}
};
结构组件类型:public std::less{
静态固定字符串最大值()
{
固定字符串s;
std::fill(s.charStr,s.charStr+MAX_KEY_LEN,0x7f);
返回s;
}
};
请注意,要使所有stxxl::map函数正常工作,需要覆盖所有运算符((),=,!=)
现在我们可以为映射定义固定的\u名称\u映射,如下所示:
struct CompareGreaterString {
bool operator () (const std::string& a, const std::string& b) const {
return a > b;
}
static std::string max_value() {
return "";
}
};
// template parameter <KeyType, DataType, CompareType, RawNodeSize, RawLeafSize, PDAllocStrategy (optional)>
typedef stxxl::map<std::string, unsigned int, CompareGreaterString, DATA_NODE_BLOCK_SIZE, DATA_LEAF_BLOCK_SIZE> name_map;
name_map strMap((name_map::node_block_type::raw_size)*3, (name_map::leaf_block_type::raw_size)*3);
for (unsigned int i = 0; i < 1000000; i++) { /// Inserting 1 million strings
std::stringstream strStream;
strStream << (i);
Console::println("Inserting: " + strStream.str());
strMap[strStream.str()]=i;
}
static const int MAX_KEY_LEN = 16;
class FixedString {
public:
char charStr[MAX_KEY_LEN];
bool operator< (const FixedString& fixedString) const {
return std::lexicographical_compare(charStr, charStr+MAX_KEY_LEN,
fixedString.charStr, fixedString.charStr+MAX_KEY_LEN);
}
bool operator==(const FixedString& fixedString) const {
return std::equal(charStr, charStr+MAX_KEY_LEN, fixedString.charStr);
}
bool operator!=(const FixedString& fixedString) const {
return !std::equal(charStr, charStr+MAX_KEY_LEN, fixedString.charStr);
}
};
struct comp_type : public std::less<FixedString> {
static FixedString max_value()
{
FixedString s;
std::fill(s.charStr, s.charStr+MAX_KEY_LEN, 0x7f);
return s;
}
};
typedef stxxl::map<FixedString, unsigned int, comp_type, DATA_NODE_BLOCK_SIZE, DATA_LEAF_BLOCK_SIZE> fixed_name_map;
fixed_name_map myFixedMap((fixed_name_map::node_block_type::raw_size)*5, (fixed_name_map::leaf_block_type::raw_size)*5);
typedef stxxl::map fixed_name_map;
固定名称映射myFixedMap((固定名称映射::节点块类型::原始大小)*5,(固定名称映射::叶块类型::原始大小)*5);
现在该程序编译良好,可以毫无问题地接受大约10^8个字符串。
此外,我们还可以使用myFixedMap,比如std::map本身。{for ex:myFixedMap[fixedString]=10}在Timo bingmann、user2079303和Martin Ba的大力帮助下,我终于找到了问题的解决方案。谢谢
我想和你分享一下
首先,stxxl只支持POD。这意味着它只存储固定大小的结构。因此std::string不能是键。stxxl::map用于大约100-1000个字符串,因为它们包含在物理内存中。当插入更多字符串时,它必须在磁盘上写入,这在内部造成了一些问题
因此,我们需要使用char[]的固定字符串,如下所示:
struct CompareGreaterString {
bool operator () (const std::string& a, const std::string& b) const {
return a > b;
}
static std::string max_value() {
return "";
}
};
// template parameter <KeyType, DataType, CompareType, RawNodeSize, RawLeafSize, PDAllocStrategy (optional)>
typedef stxxl::map<std::string, unsigned int, CompareGreaterString, DATA_NODE_BLOCK_SIZE, DATA_LEAF_BLOCK_SIZE> name_map;
name_map strMap((name_map::node_block_type::raw_size)*3, (name_map::leaf_block_type::raw_size)*3);
for (unsigned int i = 0; i < 1000000; i++) { /// Inserting 1 million strings
std::stringstream strStream;
strStream << (i);
Console::println("Inserting: " + strStream.str());
strMap[strStream.str()]=i;
}
static const int MAX_KEY_LEN = 16;
class FixedString {
public:
char charStr[MAX_KEY_LEN];
bool operator< (const FixedString& fixedString) const {
return std::lexicographical_compare(charStr, charStr+MAX_KEY_LEN,
fixedString.charStr, fixedString.charStr+MAX_KEY_LEN);
}
bool operator==(const FixedString& fixedString) const {
return std::equal(charStr, charStr+MAX_KEY_LEN, fixedString.charStr);
}
bool operator!=(const FixedString& fixedString) const {
return !std::equal(charStr, charStr+MAX_KEY_LEN, fixedString.charStr);
}
};
struct comp_type : public std::less<FixedString> {
static FixedString max_value()
{
FixedString s;
std::fill(s.charStr, s.charStr+MAX_KEY_LEN, 0x7f);
return s;
}
};
typedef stxxl::map<FixedString, unsigned int, comp_type, DATA_NODE_BLOCK_SIZE, DATA_LEAF_BLOCK_SIZE> fixed_name_map;
fixed_name_map myFixedMap((fixed_name_map::node_block_type::raw_size)*5, (fixed_name_map::leaf_block_type::raw_size)*5);
static const int MAX_KEY_LEN=16;
类FixedString{
公众:
char charStr[MAX_KEY_LEN];
布尔运算符<(常量固定字符串和固定字符串)常量{
return std::lexicographic_compare(charStr,charStr+MAX_KEY_LEN,
fixedString.charStr,fixedString.charStr+MAX\u KEY\u LEN);
}
布尔运算符==(常量FixedString和FixedString)常量{
返回std::equal(charStr,charStr+MAX_KEY_LEN,fixedString.charStr);
}
布尔运算符!=(常量固定字符串和固定字符串)常量{
return!std::equal(charStr,charStr+MAX_KEY_LEN,fixedString.charStr);
}
};
结构组件类型:public std::less{
静态固定字符串最大值()
{
固定字符串s;
std::fill(s.charStr,s.charStr+MAX_KEY_LEN,0x7f);
返回s;
}
};
请注意,要使所有stxxl::map函数正常工作,需要覆盖所有运算符((),=,!=)
现在我们可以为映射定义固定的\u名称\u映射,如下所示:
struct CompareGreaterString {
bool operator () (const std::string& a, const std::string& b) const {
return a > b;
}
static std::string max_value() {
return "";
}
};
// template parameter <KeyType, DataType, CompareType, RawNodeSize, RawLeafSize, PDAllocStrategy (optional)>
typedef stxxl::map<std::string, unsigned int, CompareGreaterString, DATA_NODE_BLOCK_SIZE, DATA_LEAF_BLOCK_SIZE> name_map;
name_map strMap((name_map::node_block_type::raw_size)*3, (name_map::leaf_block_type::raw_size)*3);
for (unsigned int i = 0; i < 1000000; i++) { /// Inserting 1 million strings
std::stringstream strStream;
strStream << (i);
Console::println("Inserting: " + strStream.str());
strMap[strStream.str()]=i;
}
static const int MAX_KEY_LEN = 16;
class FixedString {
public:
char charStr[MAX_KEY_LEN];
bool operator< (const FixedString& fixedString) const {
return std::lexicographical_compare(charStr, charStr+MAX_KEY_LEN,
fixedString.charStr, fixedString.charStr+MAX_KEY_LEN);
}
bool operator==(const FixedString& fixedString) const {
return std::equal(charStr, charStr+MAX_KEY_LEN, fixedString.charStr);
}
bool operator!=(const FixedString& fixedString) const {
return !std::equal(charStr, charStr+MAX_KEY_LEN, fixedString.charStr);
}
};
struct comp_type : public std::less<FixedString> {
static FixedString max_value()
{
FixedString s;
std::fill(s.charStr, s.charStr+MAX_KEY_LEN, 0x7f);
return s;
}
};
typedef stxxl::map<FixedString, unsigned int, comp_type, DATA_NODE_BLOCK_SIZE, DATA_LEAF_BLOCK_SIZE> fixed_name_map;
fixed_name_map myFixedMap((fixed_name_map::node_block_type::raw_size)*5, (fixed_name_map::leaf_block_type::raw_size)*5);
typedef stxxl::map fixed_name_map;
固定名称映射myFixedMap((固定名称映射::节点块类型::原始大小)*5,(固定名称映射::叶块类型::原始大小)*5);
现在该程序编译良好,可以毫无问题地接受大约10^8个字符串。
此外,我们还可以像std::map本身一样使用myFixedMap。{for ex:myFixedMap[fixedString]=10}如果您使用的是C++11,那么作为