繁体   English   中英

字符串拆分为向量<char*>覆盖向量元素

[英]String split into vector<char*> overwrites vector elements

使用https://stackoverflow.com/a/236803/6361644 中提到的以下代码,我编写了以下代码将字符串解析为向量,其中每个元素用空格分隔。

std::string line = "ls -l -a";
std::string cmd;
std::vector<char*> argv;
std::stringstream ss;
ss.str(line); 
std::string tmp;
getline(ss, cmd, ' ');
argv.push_back( const_cast<char*>(cmd.c_str() ) );
while(getline(ss, tmp, ' '))
    argv.push_back( const_cast<char*>(tmp.c_str() ) );
argv.push_back(NULL);

在此代码后打印 argv 给出

{gdb) print argv                                                                         
$22 = std::vector of length 3, capacity 4 = {0x26014 "ls", 0x2602c "-a", 0x2602c "-a", 0x0} 

我不确定为什么第二个元素被覆盖。 任何提示将不胜感激。

您正在存储悬空指针(以格式错误的方式存储!存储指向 c 样式字符串的指针的正确方法是const char* ,而不是char* )。

在这个( const更正)循环中:

std::vector<const char*> argv;
// ...
while(getline(ss, tmp, ' '))
    argv.push_back(tmp.c_str());

每次后续迭代都将清除tmp ,使您存储的前一个指针无效。 您推回的每个tmp.c_str()都会立即被getline()释放。 所以所有后续访问都是未定义的。

您必须拥有所有字符串的所有权,您可以通过存储完整string

std::vector<std::string> argv;
// ...
while(getline(ss, tmp, ' '))
    argv.push_back(std::move(tmp));

现在argv实际上拥有自己的所有资源。

c_str()返回的指针指向std::string的内部数据。

该指针仅在字符串被销毁或修改之前有效。 一旦std::string被销毁或修改,指针就不再有效。

while(getline(ss, tmp, ' '))
    argv.push_back( const_cast<char*>(tmp.c_str() ) );

抛开转换const -ness 的问题,这已经是一个危险信号:每次while循环迭代tmp的内容时,都会被ss文件中的下一行替换。

这会自动使在while循环的前一次迭代中获得的c_str()无效。

这里的正确解决方案是首先将所有单个单词解析为std::vector<std::string>

然后,一旦这个向量被初始化,迭代这个向量并获得每个单独的字符串的c_str() ,以构造原始字符指针的向量。

更好的是:使用std::vector<char>而不是std::string ,在每个向量的末尾添加一个显式的 '\\0' 字符,并且不需要丑陋的const_cast

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM