函数执行完成后,如何使分配给函数内部的内存保持分配状态?

时间:2020-04-09 21:40:22

标签: c++ memory-management

我用C ++编写了一个函数,该函数将一个字符串和一个char作为参数,并返回一个字符串数组,其中每个数组元素都是该字符串中的一个单词。

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 =新字符串[i] 分配的内存将被释放,因此我相信如果字符串输入足够大该程序重新调整的字符串数组可能会被覆盖。

如何使函数内部分配的内存在函数执行完成后仍保持分配状态?

2 个答案:

答案 0 :(得分:1)

您的理解有点偏离。

当函数退出时,R变量本身的内存确实已释放,因为RbreakS()的局部变量。但是R是一个指针,并且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;
#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

std::vector<string> words = breakS("some,string,of,words", ',');
for(size_t i = 0; i < words.size(); ++i){
    // use words[i] as needed...
}
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; } 的大小即可向其中添加新元素,因此它会根据需要动态增长,例如:

Immunodeficiency with increased immunoglobulin [M] [IgM]

答案 1 :(得分:0)

如何使函数内部分配的内存在函数执行完成后仍保持分配状态?

让我改一下(这样答案就更容易上手了):

该如何确保函数返回时未释放字符串数组?

没事!

动态内存无法正常工作。除非您调用delete [],否则永远不会自动释放内存(直到程序终止并释放所有内存)。

但是,将指针返回到字符串数组的第一个元素对调用者来说是毫无用处的,因为它们无法知道数组的大小。请改用std::vector<std::string>。它可以作为值返回,并且避免了动态c数组带来的许多问题。