C++ 如何在stxxl::map中使用std::string作为键

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

我试图使用std::string作为stxxl::map中的键 对于少量的字符串(大约10-100个),插入效果很好。 但是,当我试图在其中插入大量大约100000个字符串时,我遇到了分段错误

代码如下:

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,那么作为