c++ - 将标记转换为 char* const* 时,使用 boost 对字符串进行标记失败

标签 c++ boost boost-tokenizer

我正在使用 boost::tokenizer 在 C++ 中标记字符串,然后我想将其传递给 execv

考虑以下代码片段(可编译):

#include <iostream>
#include <cstdlib>
#include <vector>
#include <boost/tokenizer.hpp>

// I will put every token into this vector
std::vector<const char*> argc;
// this is the command I want to parse
std::string command = "/bin/ls -la -R";


void test_tokenizer() {
  // tokenizer is needed because arguments can be in quotes
  boost::tokenizer<boost::escaped_list_separator<char> > scriptArguments(
              command,
              boost::escaped_list_separator<char>("\\", " ", "\""));
  boost::tokenizer<boost::escaped_list_separator<char> >::iterator argument;
  for(argument = scriptArguments.begin(); 
    argument!=scriptArguments.end(); 
    ++argument) {

    argc.push_back(argument->c_str());
    std::cout << argument->c_str() << std::endl;
  }

  argc.push_back(NULL);
}

void test_raw() {
  argc.push_back("/bin/ls");
  argc.push_back("-l");
  argc.push_back("-R");

  argc.push_back(NULL);
}

int main() {
  // this works OK
  /*test_raw();
  execv(argc[0], (char* const*)&argc[0]);
  std::cerr << "execv failed";
  _exit(1);
  */

  // this is not working
  test_tokenizer();
  execv(argc[0], (char* const*)&argc[0]);
  std::cerr << "execv failed";
  _exit(2);
}

当我运行此脚本时,它会调用 test_tokenizer(),它将打印“execv failed”。 (尽管它很好地打印了参数)。

但是,如果我将 test_tokenizer 更改为 test_raw 它运行正常。

这一定是一些简单的解决方案,但我没有找到。

PS.:我还将其放入支持 boost 的在线编译器 here .

最佳答案

boost::tokenizer按值(默认为 std::string )将 token 保存在 token 迭代器中。

因此字符数组argument->c_str()当迭代器被修改时,指向的点可能会被修改或失效,并且其生命周期将以 argument 的生命周期结束。最晚。

因此,当您尝试使用 argc 时,您的程序会出现未定义的行为.

如果您想继续使用boost::tokenizer ,我建议将代币保留在 std::vector<std::string> 中然后将它们转换为指针数组。

关于c++ - 将标记转换为 char* const* 时,使用 boost 对字符串进行标记失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57981872/

相关文章:

c++ - 在代码中管理大量文本(并支持翻译)的最佳方式是什么?

c++ - 如何从函数中获取一 block 内存并将其写入文件?

c++ - boost::variant 的访客模板

c++ - 如何在不引起循环依赖的情况下传递然后调用通用回调函数

c++ - 使用多个定界符拆分字符串,允许引用值

c++ - C/C++中如何获取函数的执行时间

c++ - IP 头位顺序不清楚

c++ - CMake 错误查找 Boost header

C++迭代器循环与索引循环