1

我正在为 C++ 使用nlohmann::json库。我有以下代码。

#include <iostream>
#include <json.hpp>

using json = nlohmann::json;

int main(){
    json m;
    m["aaaaaaaa"] = 0;
    m["bbbbbbbbbbbbb"] = 0;
    m["ccccccccccccccccccc"] = 0;
    m["dddddddddddddddddd"] = 0;
    m["eeeeeeeeeeeeeeeeee"] = 0;
    m["fffffffffffff"] = 0;
    m["gggggggggggg"] = 0;
    m["hhhhhhhhhhhh"] = 0;
    m["iiii"] = 0;
    m["jjjjjjjjjjjjjjj"] = 0;
    m["kkkkkkkkkkkkkk"] = 0;
    m["llllllllllllllll"] = 0;

    for (int i = 0; i < 100; i++) {
        const char* mstr = m.dump().c_str();
        std::cout << strlen(mstr) << std::endl;
    }

}

我希望strlen(mstr)for 循环的所有 100 次迭代的输出完全相同。

在某些运行中,我得到了预期的输出。

223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 253 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 253程序以退出代码结束:0

但在其他运行中,我偶尔会看到字符串的长度为 0。

223 0 223 223 223 223 223 223 223 223 223 0 223 223 223 223 223 0 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 0 223 223 223 223 223 223 223 223 0 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 253程序以退出代码结束:0

这怎么可能发生?

4

2 回答 2

5

转储函数将一个对象返回到堆栈。通过使用来自该对象的指针,您可能偶尔会发现对象内存在您打印值之前被重用。应该做的是直接存储转储的字符串:

std::string mstr = m.dump();
std::cout << mstr.size() << std::endl;
于 2019-11-12T21:20:55.783 回答
4

m.dump()返回一个临时string_t对象。当到达整个表达式;的末尾时,该临时对象超出范围。const char* mstr = m.dump().c_str();这意味着当您调用它时该对象仍然是活动c_str()的,但是在您保存char*指针之后mstr但在您可以将其打印到std::cout. 指针在该点悬空,因此输出的行为是undefined

您需要保存临时对象,以便在使用指向它的指针完成之前使数据保持活动状态,例如:

for (int i = 0; i < 100; i++) {
    string_t mstr = m.dump();
    std::cout << strlen(mstr.c_str()) << std::endl;
}

然后可以简化,因为您实际上根本不需要strlen()在这种情况下使用,C++ 字符串知道它自己的长度:

for (int i = 0; i < 100; i++) {
    string_t mstr = m.dump();
    std::cout << mstr.size() << std::endl;
}

size()或者,您可以在临时对象仍在范围内时打印:

for (int i = 0; i < 100; i++) {
    std::cout << m.dump().size() << std::endl;
}
于 2019-11-12T21:32:04.107 回答