C++中std::vector<char*> push_back添加元素全为末值问题求解
错误原因
问题本质是std::vector<char*>存储的是内存指针,不是字符串的实体内容。
你在循环外定义的char txt[10]是栈上分配的单块固定内存,整个循环执行期间它的内存地址从未改变:
- 每次
sprintf调用都是把新格式化的字符串写入这同一块内存,直接覆盖上一轮写入的内容 - 每次
push_back(txt)存入vector的都是同一个地址值,没有对当前字符串做独立拷贝 - 循环结束后,txt内存中留存的是最后一次写入的
num5,vector中6个指针全部指向这同一个位置,遍历输出自然全部显示为num5。
修复方案(不使用std::string)
既然要求必须使用char*类型,就需要为每个待存入的字符串分配独立的内存空间,保证每个指针指向的内存区域互不干扰,不会被后续循环的写入操作覆盖。
修正后的元素添加代码如下:
#include <cstdio> #include <cstring> #include <vector> // 已定义的vector std::vector<char*> Lista; void add_items() { for (int x = 0; x <= 5; x++) { char txt[10]; sprintf(txt, "num%d", x); printf("Add %s\n", txt); // 单独分配堆内存,长度为字符串长度+1,预留字符串结束符'\0'的位置 char* item = new char[strlen(txt) + 1]; // 将当前txt中的字符串内容拷贝到新分配的独立内存 strcpy(item, txt); Lista.push_back(item); } }
重要提醒:上述代码用
new[]在堆上分配了内存,当你不再需要Lista中的元素时,必须遍历vector逐个释放内存,否则会出现内存泄漏:void release_list() { for (size_t i = 0; i < Lista.size(); i++) { delete[] Lista[i]; } Lista.clear(); }
修复后你原来写的遍历代码不需要改动,运行后就会正常输出num0到num5的结果。
内容的提问来源于stack exchange,提问作者Douglas Ruiz
相关产品推荐
相关产品推荐

