string_view указывает на другую строку - PullRequest
0 голосов
/ 05 июня 2019

Я использую Boost 1.70 и обнаружил довольно загадочную проблему, когда иногда boost :: string_view указывает на другую строку.

Это вызов функции, при котором boost :: string_view создается следующим образом:

boost::beast::string_view message = "The resource '" + target.to_string() + "' was not found.";
return prepareError(req, message, beast_http::status::not_found);

И это метод prepareError (), который вызывается, когда происходит что-то действительно странное. Первая версия использует message.to_string () при создании строковой переменной:

    template<class Body, class Allocator>
    beast_http::response<beast_http::string_body> prepareError(beast_http::request<Body, beast_http::basic_fields<Allocator>>& req,
        boost::beast::string_view message, beast_http::status statusCode) {
        beast_http::response<beast_http::string_body> res{statusCode, req.version()};
        res.set(beast_http::field::server, SERVER_VERSION_STRING);
        res.set(beast_http::field::content_type, MIMETYPE_JSON);
        if (_allowCrossOrigin) {
            res.set(beast_http::field::access_control_allow_origin, "*");
        }
        res.keep_alive(req.keep_alive());
        int sc = (int)statusCode;
        std::string json = std::string("{\n  error_code:") +
                            std::to_string(sc) + std::string(",\n") +
                            std::string("  error_description:\"") +
                            message.to_string() + std::string("\"\n}");

        res.body() = json;
        res.prepare_payload();
        return res;
    } 

Эта переменная json будет содержать следующую строку, например:

Printing description of json:
(std::__1::string) json = "{\n  error_code:404,\n  error_description:\"{\n  error_code:404,\n  error_descript\"\n}"

Это действительно странно. В отладчике переменная сообщения содержит пустую строку. И как вы можете видеть из вызова метода, это не должно быть ожидаемым результатом для этой строки.

Это тот же метод, с той лишь разницей, что существует временное присвоение переменной сообщения, которая является string_view, std :: string.

    template<class Body, class Allocator>
    beast_http::response<beast_http::string_body> prepareError(beast_http::request<Body, beast_http::basic_fields<Allocator>>& req,
        boost::beast::string_view message, beast_http::status statusCode) {
        beast_http::response<beast_http::string_body> res{statusCode, req.version()};
        res.set(beast_http::field::server, SERVER_VERSION_STRING);
        res.set(beast_http::field::content_type, MIMETYPE_JSON);
        if (_allowCrossOrigin) {
            res.set(beast_http::field::access_control_allow_origin, "*");
        }
        res.keep_alive(req.keep_alive());
        int sc = (int)statusCode;
        std::string msg = message.to_string();
        std::string json = std::string("{\n  error_code:") +
                            std::to_string(sc) + std::string(",\n") +
                            std::string("  error_description:\"") +
                            msg + std::string("\"\n}");

        res.body() = json;
        res.prepare_payload();
        return res;
    }

Это дает ожидаемую строку:

Printing description of json:
(std::__1::string) json = "{\n  error_code:404,\n  error_description:\"The resource '/zones' was not found.\"\n}"

Ответы [ 2 ]

3 голосов
/ 05 июня 2019

Ваша ошибка исходит от

boost::beast::string_view message = "The resource '" + target.to_string() + "' was not found.";

Вы создаете временную строку с правой стороны и устанавливаете представление так, чтобы оно указывало на нее.После окончания строки эта временная строка уничтожается, и ваше представление теперь указывает на недопустимую память.

Что вам нужно сделать, это передать временное значение непосредственно в функцию, например:

return prepareError(req, "The resource '" + target.to_string() + "' was not found.", beast_http::status::not_found);

Или запишите результат в переменную std::string, а затем передайте его в функцию.

1 голос
/ 05 июня 2019

Ошибка от:

boost::beast::string_view message = "The resource '" + target.to_string() + "' was not found.";

Вы строите временный string, который заканчивается в конце оператора. Итак, у вас есть висячий вид на следующей строке.

Вы должны построить строку там напрямую.

...