从 C++ 运行的进程偶尔会错过某个选项
the process that run from c++ misses an option occasionally
下面是我的代码,选项"--graph"有时会丢失,即使在同一台计算机上也是如此。
boost::filesystem::path cmd =
boost::filesystem::path(my::Cmdline::get_workspace())
/ "bin" / "cmdbin";
char const *argv[1024] = {};
int idx = 0;
argv[idx++] = cmd.c_str();
argv[idx++] = ("--graph=" + conf.root()).c_str();
argv[idx++] = "--file=/home/cmd/cmd.pid";
argv[idx++] = "--logfile=/home/cmd/cmd.log";
_exit(execvp(argv[0], (char **)argv));
// ps aux and grep the process
root 25323 4.3 0.0 1370872 10720 ? S<l 17:11 0:00 /home/cmd/cmdbin --logfile=/home/cmd/cmd.log --file=/home/cmd/cmd.pid
// which should be
root 25323 4.3 0.0 1370872 10720 ? S<l 17:11 0:00 /home/cmd/cmdbin --graph=/home/cmd --file=/home/cmd/cmd.pid --logfile=/home/cmd/cmd.log
顺便说一下,"conf.root(("是一个内联函数;它与execvp有关吗? 给它时缺少 argv?
您正在使用临时字符串对象("--graph=" + conf.root())
的c_str
方法,该方法返回指向该字符串对象的内部缓冲区的指针,该指针在该行之后不再有效。
您可以改用它:
std::string graph_option = "--graph=" + conf.root();
argv[idx++] = graph_option.c_str();
这个字符串在execvp
之前不会被删除,因为变量之前不会超出范围。
它有时与无效对象一起工作的原因是返回的指针仍将指向缓冲区以前所在的位置。当您调用c_str
对象仍然有效时,即使不是,您仍然可以从该方法中获得一些东西,通常不会在对象被销毁后检查使用对象。
如果在析构函数调用和使用值之间碰巧没有覆盖该缓冲区,则将读取旧值,并且一切似乎都正常工作。根据字符串实现和字符串的大小,缓冲区可能位于堆上或字符串对象本身内部(在堆栈上(。无论哪种方式,内存都可以重复使用或不重复使用。您可以使用调试器来检查系统上实际发生的情况,但是即使对程序的不相关部分,标准库或编译器的任何更改都可能会更改结果。
C++的一个关键概念是"未定义的行为"一词。这意味着如果违反某些条件,则绝对没有限制程序中发生的情况。这允许语言的实现者(主要是编译器和标准库(进行优化,假设未定义的行为永远不会发生。
相关文章:
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- Win32编译器选项和内存分配
- C/C++预处理器是否可以检测一些编译器选项
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 通过选项卡的文本设置QTabWidget顺序
- 通过ccmake在cmake中缓存依赖选项
- 如何传递多个 std::文件系统选项?
- 基于编译器选项的编译二进制路径
- "perf_event_attr"结构的"read_format"属性的选项到底是什么?
- 如何应用 libcurl 的持久连接选项
- 文件中.dat Dlib 选项
- LLVM | codegen 用于带有命令行选项的程序输入功能
- 编译 Boost 时在 OS X 上的"ld:未知选项:-soname"
- 按钮悬停在 QT 中垂直布局的选项卡小部件中不起作用
- Visual Studio C++ 它只构建选项卡中显示的文件吗?
- 在C++不适用于猜数字游戏的情况下再次播放选项
- Qt5 用户界面编译器:-i 选项不可用
- CMake - 更改共享库链接选项
- 从 C++ 运行的进程偶尔会错过某个选项