从字符串 stringstream 获取 const ptr 时的行为

Posted

技术标签:

【中文标题】从字符串 stringstream 获取 const ptr 时的行为【英文标题】:Behavior when fetching const ptr from string stringstream 【发布时间】:2015-07-06 09:40:07 【问题描述】:

我有以下代码,我试图了解它的行为:

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

using namespace std;

void fill(std::vector<const char *> & vec, string str) 
   uint32_t start_count = 1;
   stringstream regname;
   for(uint32_t count = 0; count <= 3; count++) 
      regname.str("");
      regname << str << (uint32_t)(count + start_count);
      std::cout << "regname : " << regname.str() << std::endl;
      vec.push_back(regname.str().c_str());
   


int main() 
   vector<const char *> vec;
   fill(vec, "temp");

   for(int i = 0; i < vec.size(); i++)
      std::cout << "value at index : " << i << " is  : " << vec[i] << std::endl;
   return 0;

向量中的初始字符串打印正确,但是对于在填充方法中初始化的字符串,我得到所有带有“temp4”的实例,这是最后一个初始化的字符串。 使用 const char * 的 std::vector 时的 O/P :

regname : temp1
regname : temp2
regname : temp3
regname : temp4
value at index : 0 is  : temp4
value at index : 1 is  : temp4
value at index : 2 is  : temp4
value at index : 3 is  : temp4

当我尝试改用 std::vector 时,此行为已得到纠正。 使用字符串对象的 std::vector 时的 O/P:

regname : temp1
regname : temp2
regname : temp3
regname : temp4
value at index : 0 is  : temp1
value at index : 1 is  : temp2
value at index : 2 is  : temp3
value at index : 3 is  : temp4

只是想知道是什么导致了这种行为?

【问题讨论】:

使用std::vector&lt;std::string&gt;vec.push_pack(regname.str()) 让你的痛苦消失。也只需使用从14count,而不是那个愚蠢的添加。 【参考方案1】:

在 regname 上调用 str 将返回流内容的字符串副本。对该字符串调用c_str 将返回一个指向包含该字符串中字符序列的数组的指针。

显然,您推回该数组的指针对于所有 4 次循环迭代都是相同的,并且在调用 fill 方法后打印它们将打印四次相同的内容。

您当前的代码是不安全的,因为字符串在您的填充方法中是临时的,并且指向其内部字符数组的指针在从fill 返回后会悬空。最好使用 vec 向量中的字符串来存储真实副本。

【讨论】:

但是当我将它推入向量时,它不会创建指针的不同实例。即使我在循环中声明了字符串流,结果仍然是一样的。 它将复制指针,而不是指针指向的位置的数据。 谁一直在教指针如此糟糕以至于人们觉得需要长期存储它们并认为它们“是”字符串? :(【参考方案2】:

push_back() 之前,动态分配内存以在函数的调用帧被清除后保留它。如下所示(参见http://ideone.com/aR0f98 演示)

#include <cstring>

...
char * p = new char[regname.str().length() + 1];
strcpy(p, regname.str().c_str());
vec.push_back(p);

使用后记得删除,防止内存泄漏。但是,这是推荐的。这里推荐使用std::string

【讨论】:

以上是关于从字符串 stringstream 获取 const ptr 时的行为的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中使用 stringstream 获取字符串中的所有 N 个连续字符

从 stringstream 到 string 的转换会删除 '=' 字符

用stringstream实现从数字到字符串的转化

C++ Stringstream 只拾取第一个字符串

如何使用javascript从stringstream内容azure blob存储中下载png文件

“stringstream”是不是复制构造它的字符串?