string and const char* and .c_str()?
string and const char* and .c_str()?
我遇到了一个奇怪的问题,我想知道为什么它会这样做。我有一个类,其中有一个成员函数返回std::string
。我的目标是将这个string
转换为const char*
,因此我执行了以下操作
const char* c;
c = robot.pose_Str().c_str(); // is this safe??????
udp_slave.sendData(c);
问题是我在Master这边得到了一个奇怪的角色。但是,如果我执行以下操作
const char* c;
std::string data(robot.pose_Str());
c = data.c_str();
udp_slave.sendData(c);
我得到了我所期待的。我的问题是,上述两种方法有什么区别?
这是一个指向临时的问题。如果按值返回,但不存储string
,它将在下一个序列点(分号)之前消失。
如果你把它存储在一个变量中,那么指针指向的是在你的udp发送期间实际存在的东西
考虑以下内容:
int f() { return 2; }
int*p = &f();
这看起来很傻,不是吗?您指向的是正在从f
复制回来的值。你不知道它能活多久。
你的string
也是这样。
.c_str()
按值返回char const*
的地址,这意味着它获得了指针的副本。但在那之后,它所指向的实际字符数组被销毁。这就是为什么你会得到垃圾。在后一种情况下,您将通过从实际位置复制字符来创建具有该字符数组的新字符串。在这种情况下,虽然实际的字符数组被销毁,但副本仍然保留在字符串对象中。
您不能使用c_str()
所指向的超过std::string
对象生命周期的数据。有时不清楚生命周期是什么,例如下面的代码。解决方案也给出了:
#include <string>
#include <cstddef>
#include <cstring>
std::string foo() { return "hello"; }
char *
make_copy(const char *s) {
std::size_t sz = std::strlen(s);
char *p = new char[sz];
std::strcpy(p, s);
return p;
}
int
main() {
const char *p1 = foo().c_str(); // Whoops, can't use p1 after this statement.
const char *p2 = make_copy(foo().c_str()); // Okay, but you have to delete [] when done.
}
From c_str():
从c_str()中获得的指针可能会被以下方式无效:
- 将字符串的非const引用传递给任何标准库函数,或者
- 在字符串上调用非const成员函数,不包括操作符[]、at()、front()、back()、begin()、rbegin()、end()和撕裂()。
这意味着,如果robot.pose_Str()
返回的字符串被销毁或被任何非const函数更改,指向该字符串的指针将失效。由于您可能会从robot.pose_Str()
返回一个临时副本,因此在调用之后返回c_str()
将是无效的。
但是,如果返回对可能持有的内部字符串的引用,而不是临时副本,则可以:
- 确保它会工作,如果你的函数
udp_send
是同步的; - 或者依赖于一个无效的指针,如果
udp_send
可能在对原始字符串的内部内容进行一些可能的修改后完成,则会经历未定义的行为。
Q
const char* c;
c = robot.pose_Str().c_str(); // is this safe??????
udp_slave.sendData(c);
这可能不安全。这取决于robot.pose_Str()
返回什么。如果返回的std::string
的寿命比c
的寿命长,则它是安全的。
您在c
中存储的地址在语句执行完成后将无效。
std::string s = robot.pose_Str();
const char* c = s.c_str(); // This is safe
udp_slave.sendData(c);
这里,您在c
中存储了一个地址,该地址将在您离开s
和c
定义的作用域时有效。
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 为什么C++逐位AND运算符在不同大小的操作数中表现为这样
- 为什么 Clang 不允许"and"作为函数名称?
- Python str to C++ to Python str
- 位阵列上的快速AND运算
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- BoostPython and CMake
- 为什么无论你输入什么,这"while(cin.get(str,3))"只运行一次?
- OpenSSL BIO and SSL_read
- 字符串变量,比如说"字符串str",可以直接复制到数组中吗?
- Gurobi GRBModel and GRBmodel in C++
- 解释一下 for (char c : str) 的作用?
- 返回 str vs. str.substr(0,str.size()) 在 leetcode 中给了我不同的输出
- remove(str.begin(), str.end(), );无法正常工作(我正在使用视觉工作室 2012)
- Getline(cin,str)的奇怪输出
- std::visit and std::variant usage
- SHBrowseForFolder with BIF_BROWSEFORCOMPUTER and SHGetPathFr
- Directx12 and keystrokes
- using str::find and find_first_of and last_of
- std::stringstream and the str method