use*_*835 1 c++ string vector char std-filesystem
运行这个程序
#include <iostream>
#include <filesystem>
#include <vector>
using namespace std;
namespace fs = filesystem;
int main() {
vector<fs::path> paths{"a.o", "b.o"};
vector<const char *> argv{};
for (auto &p : paths) {
argv.push_back(p.string().data()); // line A
}
argv.push_back(paths[0].string().data());
argv.push_back(paths[1].string().data());
for (auto &s : argv) {
cout << s << endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
得到
b.o
b.o
a.o
b.o
Run Code Online (Sandbox Code Playgroud)
为什么 argv 的第一个元素不是“ao”?
我尝试在A线断,找出当“博”是的push_back()插入的argv,argv的的第一个元素改变从“AO”到“博”。
然后,当我将 A 行更改为
argv.push_back(p.string().c_str()); // line A: .string().data() -> .string().c_str()
Run Code Online (Sandbox Code Playgroud)
结果一样。
当我将 A 行更改为
argv.push_back(p.c_str()); // line A: .string().data() -> .c_str()
Run Code Online (Sandbox Code Playgroud)
突然,我得到了预期的结果:
a.o
b.o
a.o
b.o
Run Code Online (Sandbox Code Playgroud)
有人可以解释奇怪的行为以及 .string().data() 和 .c_str() 之间的区别吗?
问题是该path::string()函数按值返回字符串。
一个将在表达式结束后立即销毁的值p.string().data()。
这意味着指针将立即无效,并且当您尝试取消引用它时(例如打印时),您将有未定义的行为。
显而易见的解决方案是不对char*字符串使用向量,而是使用向量std::string。
至于使用p.string().data()(或p.string().c_str()) 和之间的区别p.c_str(),在于p.c_str()返回一个指向path由 引用的对象内部的内部字符串的指针p。该path对象将不会被破坏,直到任一clear所述的载体或载体的寿命时间(及其包含的对象)的端部(当载体被破坏)。
请注意,如果您使用了循环,例如
for (auto p : paths) { ... }
Run Code Online (Sandbox Code Playgroud)
wherep是path对象的副本,那么即使使用p.c_str(),您也会遇到相同的问题,因为对象p将结束其生命周期并在循环的每次迭代结束时被销毁。
| 归档时间: |
|
| 查看次数: |
79 次 |
| 最近记录: |