c++ - 函数执行完成后,如何使函数内部分配的内存保持分配状态?
问题描述
我用 C++ 编写了一个函数,它接受一个字符串和一个字符作为参数,并返回一个字符串数组,其中每个数组元素都是字符串中的一个单词。
string* breakS(string s, const char* c){
string::iterator it;
int j=0, i = 1;
for(it = s.begin();it!=s.end();it++){
if(*it == *c){
i++;
}
}
string* R = new string[i];
for(it = s.begin();it!=s.end();it++){
if(*it != *c){
R[j].push_back(*it);
} else {
j++;
}
}
return R;
}
因为我永远不知道输入字符串会有多少个单词,所以我不得不动态分配字符串数组。
该程序运行良好,但是当函数完成执行时,由 string* R = new string[i]分配的内存将被释放,因此我相信如果字符串输入足够大,则该程序重新调整的字符串数组可能是覆盖。
函数执行完成后,如何使函数内部分配的内存保持分配状态?
解决方案
你的理解有点不对劲。
R
当函数退出时,变量本身的内存确实被释放,R
局部变量也是如此breakS()
。ButR
是一个指针,当函数退出时,R
所指向的内存,被分配的内存,new[]
不会被自动释放。delete[]
完成使用后,它成为调用者对该内存的责任,例如:
string* breakS(string s, char c, int &numWords){
numWords = 0;
string::iterator it;
int i = 1;
for(it = s.begin(); it != s.end(); ++it){
if (*it == c){
++i;
}
}
string* R = new string[i];
i = 0;
for(it = s.begin(); it != s.end(); ++it){
if (*it != c){
R[i].push_back(*it);
} else {
++i;
}
}
numWords = i;
return R;
}
int numWords;
string *words = breakS("some,string,of,words", ',', numWords);
for (int i = 0; i < numWords; ++i) {
// use words[i] as needed...
}
delete[] words;
处理这种内存管理的更好方法是使用std::vector
:
#include <vector>
std::vector<string> breakS(string s, char c){
string::iterator it;
int i = 1;
for(it = s.begin(); it != s.end(); ++it){
if (*it == c){
++i;
}
}
std::vector<string> R(i);
i = 0;
for(it = s.begin(); it != s.end(); ++it){
if (*it != c){
R[i].push_back(*it);
} else {
++i;
}
}
return R;
}
std::vector<string> words = breakS("some,string,of,words", ',');
for(size_t i = 0; i < words.size(); ++i){
// use words[i] as needed...
}
然后可以进一步简化,因为您不需要预先调整 a 的大小std::vector
来添加新元素,它会根据需要动态增长,例如:
std::vector<string> breakS(string s, char c){
std::vector<string> R;
string::size_type start = 0, idx = s.find(c);
while (idx != string::npos){
R.push_back(s.substr(start, idx-start));
start = idx + 1;
idx = s.find(c, start);
}
if (start < s.size()){
R.push_back(s.substr(start));
}
return R;
}
推荐阅读
- docker - 带有 EF Core 和 K8s 的 .NET 和 SQL Server 容器
- ansible - 运行 Ansible 角色以禁用密码登录后权限被拒绝(公钥)
- datadog - 为什么 Datadog 不捕获标签?
- python - set_position() 之后的 matplotlib twinx 奇怪行为
- python-3.x - Python:打开文件并显示进度
- python - 如何防止 __init__ 在目录中运行?
- javascript - 将“this”传递给另一个函数不起作用
- flutter - Timer.periodic() 回调干扰 GestureDetector
- css - 如何删除每个反应视图底部的空格?
- docker - 如何使用常规方式运行基于 docker 的 mssql-tools