c++ - push_back() a filesystem::path 的 .string().data() 的奇怪行为导致“向量"
问题描述
运行这个程序
#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;
}
得到
b.o
b.o
a.o
b.o
为什么 argv 的第一个元素不是“ao”?
我尝试在 A 行中断,发现当“bo”是 push_back() 进入 argv 时,argv 的第一个元素从“ao”变为“bo” 。
然后,当我将 A 行更改为
argv.push_back(p.string().c_str()); // line A: .string().data() -> .string().c_str()
结果相同。
当我将 A 行更改为
argv.push_back(p.c_str()); // line A: .string().data() -> .c_str()
突然我得到了预期的结果:
a.o
b.o
a.o
b.o
有人可以解释奇怪的行为以及 .string().data() 和 .c_str() 之间的区别吗?
解决方案
问题是该path::string()
函数按值返回字符串。
表达式结束后立即销毁的值。p.string().data()
这意味着指针将立即变得无效,并且当您尝试取消引用它时(例如打印它时) ,您将有未定义的行为。
显而易见的解决方案是不使用向量的char*
字符串,而是使用向量std::string
。
至于 using p.string().data()
(or p.string().c_str()
) 和之间的区别p.c_str()
,它是返回一个指针,指向由 .引用p.c_str()
的对象内部的内部字符串。在向量或向量(及其包含的对象)的生命周期结束(当向量被破坏时)之前,该对象不会被破坏。path
p
path
clear
请注意,如果您使用循环,例如
for (auto p : paths) { ... }
wherep
是path
对象的副本,那么即使使用 ,您也会遇到同样的问题p.c_str()
,因为对象p
将结束其生命并在循环的每次迭代结束时被破坏。
推荐阅读
- python-3.x - Python 3 - 拆分 PDF 文件
- php - 将连续字符添加到 id
- google-app-maker - Google App Maker:如何以编程方式隐藏微调器?
- python - 给定需要添加的空格数量,通过在单词之间添加空格来格式化字符串
- html - 为什么当我给出 z-index 时位置粘性内容会消失
- c# - 如何使用 EF Core 选择列表中不在表中的值?
- python - RaspBerry 找不到 pip3
- python - Odoo Studio 服务器错误计算字段,错误
- c# - 当我第二次单击捕获按钮时“错误:DP_Device_Failure”使用 DPUru 5100
- reactjs - 使用 TypeScript 的反应测试库:设置输入的值