字符串拆分为矢量<字符*>覆盖矢量元素
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
属性的问题,这已经是一个危险信号:每次while
循环迭代时,tmp
的内容都会被ss
文件中的下一行所替换。
这将自动使在while
循环的前一次迭代中获得的c_str()
无效。
这里的正确解决方案是首先将所有单个单词解析为std::vector<std::string>
。
然后,在vector对象初始化之后,遍历vector对象并获得每个字符串的c_str()
,以构造包含原始字符指针的vector对象。
甚至更好:使用std::vector<char>
代替std::string
,在每个向量的末尾添加一个显式的' '字符,丑陋的const_cast
将不需要。
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 使用函数"remove"删除重复元素
- 具有最大子序列大小的序列,每个元素都相同
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将元素添加到数组的线程安全函数?
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 我想访问std::unique_ptr中的一个特定元素
- 如何通过 getter 函数删除矢量的元素?
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 从控制台中删除最后打印的元素
- 擦除while循环中迭代的元素