C++ 从字符串stringstream获取常量ptr时的行为

C++ 从字符串stringstream获取常量ptr时的行为,c++,string,vector,C++,String,Vector,我有以下代码,我正试图了解其行为: #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; stringstrea

我有以下代码,我正试图了解其行为:

#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;
}
当我尝试改用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

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

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

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

当前代码不安全,因为字符串是fill方法中的临时字符串,从
fill
返回后,指向其内部字符数组的指针将悬空。最好使用
vec
vector中的字符串来存储真正的副本。

push_back()
之前,动态分配内存以在清除函数的调用帧后保留它。类似于下面的内容(参见演示)

#包括
...
char*p=新字符[regname.str().length()+1];
strcpy(p,regname.str().c_str());
向量推回(p);

记住在它被用来防止内存泄漏后删除它。但是,这是不推荐的。这里建议使用
std::string

但是当我将相同的内容放入向量时,它不会创建不同的指针实例。即使我在循环中声明stringstream,结果仍然是一样的。它将复制指针,而不是指针指向的位置的数据。谁一直教指针这么差,以至于人们觉得需要长期存储它们,并认为它们“是”字符串(使用
std::vector
vec.push_-pack(regname.str())
来消除你的痛苦。也只需使用
count
1
4
而不是那种愚蠢的加法。
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
#include <cstring>

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