【问题标题】:Inequality of c_str() and char* in C++C++ 中 c_str() 和 char* 的不等式
【发布时间】:2019-03-08 04:19:08
【问题描述】:

我相信我刚刚找到了过去几天一直困扰我的错误,但它的影响让我非常头疼。

我在 macOS mojave 机器上,使用本地 libcurl 工具(在 /usr/lib 中),但我认为 cURL 本身不是问题。

我一直在尝试使用以下代码向 Twitter 提交 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() 产生的值不同?

【问题讨论】:

  • std::string 超出范围时会破坏其字符串,但 const char* 文字不会被破坏。难道curl_easy_setopt 要求传递的字符串比包含std::string 的函数寿命更长?
  • 我强烈建议您使用调试器单步执行您的代码,以便您可以检查 grantTypegrantType.c_str() 的值
  • 非常感谢,确保字符串不会被破坏超出范围工作完美!刚刚尝试(暂时)“curl_easy_setopt(curl, CURLOPT_URL, "api.twitter.com/oauth2/token"); std::string* s = new std::string("grant_type=client_credentials"); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, s->c_str());"
  • 不确定如何将答案归功于您,如果您想创建一个我会接受它(或者我可以制作一个引用您的评论的)。
  • @Makiah“确保字符串不会在范围之外被破坏完美!” - 如果你事先有read the documentation,你会知道的。仅供参考,您对new 字符串的“解决方案”是等待发生的内存泄漏,如果您在 libcurl 完成使用后不delete 字符串

标签: c++ twitter oauth libcurl


【解决方案1】:

仅考虑您的第二个项目,代码中的断言检查的第二部分:

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

是比较 string1.c_str() 存储的地址和 string2 存储的地址,它们会有所不同。

【讨论】:

  • 谢谢!我不熟悉 C char* 内容比较语法,不知道这只是检查指针值(回想起来很有意义)。
【解决方案2】:

原来实际上是一个字符串生命周期问题,alter igel 指出:CURL_POSTFIELDS 必须在稍后执行时访问字符串值,但此时字符串已经超出范围并被删除记忆。创建变量作为方法的参数必须自动创建一个不会被编译器尽快销毁的 char* 文字,从而导致我在上面概述的行为。谢谢您的帮助!

【讨论】:

  • 这是 libcurl 的 CURL_POSTFIELDS 文档中记录的行为:“指向的数据不会被库复制:因此,它必须由调用应用程序保留,直到关联传输完成。可以通过设置 CURLOPT_COPYPOSTFIELDS 选项来更改此行为(因此 libcurl 会复制数据)。"
  • 这是一个我什至不知道的关键字,谢谢你的建议!
猜你喜欢
  • 2013-07-09
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 2013-11-14
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
  • 1970-01-01
相关资源
最近更新 更多