Map.find()如何工作,查看输出的组件



我在Android应用程序上调试崩溃,并遇到以下几行:

void myobject::save(std::string toSave) {
...
}
...
std::map<std::string, std::string> dict;
...    
myobject::save(dict.find("username")->second);

由此产生的组件:

02F05DFC               bl         _ZNKSt6__ndk16__treeINS_12__value_typeINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEES7_EENS_19__map_value_compareIS7_S8_NS_4lessIS7_EELb1EEENS5_IS8_EEE4findIS7_EENS_21__tree_const_iteratorIS8_PNS_11__tree_nodeIS8_PvEEiEERKT_
3096                   str        r6, [sp, #0x108 + var_48]
0146                   mov        r1, r0
CDE92E66               strd       r6, r6, [sp, #0x108 + var_50]
11F81C2F               ldrb       r2, [r1, #0x1c]!
12F0010F               tst.w      r2, #0x1
06D1                   bne        loc_THERE
                  loc_FIRST:
D1E90002               ldrd       r0, r2, [r1]
8968                   ldr        r1, [r1, #0x8]
3091                   str        r1, [sp, #0x108 + var_48]
CDE92E02               strd       r0, r2, [sp, #0x108 + var_50]
04E0                   b          loc_HERE
                  loc_THERE:
D0E90821               ldrd       r2, r1, [r0, #0x20]
2EA8                   add        r0, sp, #0xb8_ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcj
FDF743FD               bl         _ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcj
                  loc_HERE:
2EA9                   add        r1, sp, #0xb8
2046                   mov        r0, r4
04F047FB               bl         _ZN6myobject11saveENSt6__ndk112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE

我发现了错误。当Find((返回end((迭代器时,崩溃就会发生。但是,有趣的是,崩溃发生在new((内(在basic_string :: __ init((中完成(。当find((返回end((迭代器时,似乎end(((((end(( -> second(的删除不会崩溃,但是当它转换为end(( ->第二((将其传递给MyObject :: save((。

我试图研究LibCXX实现,但没有找到我想要的东西。有人知道两个块loc_first和loc_的目的是什么?为什么检查 *(r1 0x1c(== 0x1?有人可以向我解释" ->第二"在汇编代码中发生在哪里?

我认为它正在进行一个小的字符串优化(SSO(。loc_first情况是将字符串包含在SSO缓冲区中的情况,并且只需将字符串的12个字节直接复制到字符串的堆栈位置中即可。loc_是当SSO不活跃并调用std :: string :: __ INIT进行分配和其他非SSO Init工作时。因此,从本质上讲,分支是已将其插入此代码的STD :: String Construction的一部分(但慢速的非SSO路径仍然不合时宜(。被检查的位可能表明该字符串是否有效。 - Beeonrope 3月27日在21:02

最新更新