Неравенство c_str () и char * в C ++ - PullRequest
0 голосов
/ 03 октября 2018

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

Я нахожусь на мохаве macOS, использую локальный инструмент libcurl (в / usr / lib), но я не думаю, что проблема заключается в самом cURL.

Я пытался отправить запрос OAuth2 в Твиттер, используя следующий код, все заголовки правильно указаны (не показаны).

// supplying https://api.twitter.com/oauth2/token?grant_type=client_credentials for ease of use
curl_easy_setopt(curl, CURLOPT_URL, "https://api.twitter.com/oauth2/token");
std::string grantType = "grant_type=client_credentials";
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, grantType.c_str());

Однако с кодом состояния это не получается

{"errors":[{"code":170,"message":"Missing required parameter: grant_type","label":"forbidden_missing_parameter"}]}

Смутившись, я сделал снимок:

curl_easy_setopt(curl, CURLOPT_URL, "https://api.twitter.com/oauth2/token");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "grant_type=client_credentials");

, который отлично работает:

{"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAAIMu6QAAAAAArr86Rv2W70fTicd4yAir7..."}

Так что либо я не понимаю ключевой аспект C ++, либо я нарушил вселенную - почему вызов c_str () не приводит к тому же результату?

Я также запустил следующее в отдельном проекте, чтобы попытаться понять, что происходит.

std::string string1 = "test";
char* string2 = "test";
assert((strcmp(string1.c_str(), string2)) || (string1.c_str() == string2));

Почему определение char * не приводит к тому же значению, что и определение строки, а затем вызывает c_str ()?

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Оказалось, что это на самом деле проблема жизненного цикла строки, на что указал igel: CURL_POSTFIELDS должен получить доступ к строковому значению на более позднем этапе выполнения, но в этот момент строка уже вышла бы из области видимости и была удалена изобъем памяти.Создание переменной в качестве параметра метода должно автоматически создавать литерал char *, который не уничтожается компилятором так быстро, что приводит к поведению, которое я описал выше.Спасибо за помощь!

0 голосов
/ 03 октября 2018

Просто рассматривая ваш второй проект, вторая часть проверки утверждения в коде:

std::string string1 = "test";
char* string2 = "test";
assert((strcmp(string1.c_str(), string2)) || (string1.c_str() == string2));

сравнивает адрес, где хранится string1.c_str (), с адресом, где хранится string2, иони будут разными.

...