简体   繁体   中英

How can i make memory allocated inside a function remain allocated when the function execution is finished?

I wrote a function in C++ that takes a string and a char as arguments, and return an array of strings where every array element is a word from the string.

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;
}

Since I never know how many words the input string will have, I had to dynamically allocate the array of strings.

This program runs fine, but when the function finishes its execution the memory allocated by string* R = new string[i] will be deallocated, so I believe that if the string input is big enough the array of strings retuned by this program may be overwrited.

How can I make memory allocated inside a function remain allocated when the function execution is finished?

Your understanding is a bit off.

The memory for the R variable itself is indeed released when the function exits, as R is a local variable to breakS() . But R is a pointer, and the memory that R is pointing at, the memory that is being allocated with new[] , will NOT be freed automatically when the function exits. It becomes the caller's responsibility to delete[] that memory when done using it, eg:

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;

A better way to handle this memory management is to use std::vector instead:

#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...
}

Which can then be simplified further, as you don't need to pre-size a std::vector in order to add new elements to it, it grows dynamically as needed, eg:

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;
}

How can i make memory allocated inside a function remain allocated when the function execution is finished?

Let me rephrase (so the answer is more catchy):

What do I have to do to make sure the string array is not deallocated when the function returns?

Nothing!

Dynamic memory does not work that way. Unless you do call delete [] , the memory gets never deallocated automatically (until your program terminates and all memory is released).

However, returning the pointer to the first element of the string array is rather useless for the caller, because they have no way to know the size of the array. Use a std::vector<std::string> instead. It can be returned as value and avoids many problems that come with dynamic c-arrays.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM