Map at() 对于与看似相同的字符串文字键存在的值抛出 std::out_of_range

nab*_*ekt -4 c++ string dictionary

我有一个使用字符串文字(我认为这就是它们是什么?)作为键的地图。该地图名为codingRateMap. 如果我尝试使用codingRateMap.at()字符串文字来访问它,我会得到我所期望的结果。但是,如果我尝试使用std::string c_str()返回值进行访问,则at()调用会抛出std::out_of_range。我找不到两个字符串文字之间的任何区别。printf打印同样的东西。strcmp()说他们是平等的。通过空终止符,实际字节值是相同的。

代码:

#include <map>
#include <string>
#include <string.h>
#include <stdio.h>


typedef enum
{
    CODING_RATE_4_5,  // Modem default
    CODING_RATE_4_6
} lora_modem_cfg_coding_rate_t;

static std::map<const char*, lora_modem_cfg_coding_rate_t> CreateCodingRateMap()
{
    std::map<const char*, lora_modem_cfg_coding_rate_t> newMap;
    newMap["CODING_RATE_4_5"] = CODING_RATE_4_5;
    newMap["CODING_RATE_4_6"] = CODING_RATE_4_6;
    return newMap;
}


int main(void)
{
    std::map<const char*, lora_modem_cfg_coding_rate_t> codingRateMap = CreateCodingRateMap();

    const char* coding_rate_selection1 = "CODING_RATE_4_5";

    std::string coding_rate_selection2_string = "CODING_RATE_4_5";
    const char* coding_rate_selection2 = coding_rate_selection2_string.c_str();

    printf("coding_rate_selection1: %s\n", coding_rate_selection1);
    printf("coding_rate_selection2: %s\n", coding_rate_selection2);
    printf("coding_rate_selection1 strlen: %ld\n", strlen(coding_rate_selection1));
    printf("coding_rate_selection2 strlen: %ld\n", strlen(coding_rate_selection2));
    printf("strcmp: %d\n", strcmp(coding_rate_selection1, coding_rate_selection2));

    for (uint8_t idx = 0; idx < 20; idx++)
        printf("%2d %02X %02X\n", idx, coding_rate_selection1[idx], coding_rate_selection2[idx]);
    printf("\n");

    lora_modem_cfg_coding_rate_t codingRate;
    codingRate = codingRateMap.at(coding_rate_selection1);
    printf("%s %d\n", __FILE__, __LINE__);  fflush(stdout);

    codingRate = codingRateMap.at(coding_rate_selection2);
    printf("%s %d\n", __FILE__, __LINE__);  fflush(stdout);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

coding_rate_selection1: CODING_RATE_4_5
coding_rate_selection2: CODING_RATE_4_5
coding_rate_selection1 strlen: 15
coding_rate_selection2 strlen: 15
strcmp: 0
 0 43 43
 1 4F 4F
 2 44 44
 3 49 49
 4 4E 4E
 5 47 47
 6 5F 5F
 7 52 52
 8 41 41
 9 54 54
10 45 45
11 5F 5F
12 34 34
13 5F 5F
14 35 35
15 00 00
16 43 0A
17 4F D7
18 44 39
19 49 C4

map_test.cpp 47
terminate called after throwing an instance of 'std::out_of_range'
  what():  map::at
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

这里有什么想法吗?请原谅 C 和 C++ 主义的混合。我对前者比后者更满意。谢谢你!

Moo*_*uck 6

你告诉你map用作const char*钥匙,所以它就这么做了。它使用指针作为键。如果您给它一个不同的指针,那么它会将其映射到不同的映射条目。没有涉及任何魔法,因此它不知道您希望它取消引用指针。

显而易见的解决方案是使用std::stringorstd::string_view作为键。

  • @nabelekt你没有义务这样做,但是,如果你想正确感谢答案的作者,你可以通过接受给出的答案来做到这一点。 (2认同)