do I must release memory for "string* settings = new string[4]" in c++ in linux?
I am currently debugging some legacy c++ programs that runs in linux OS (centos 5). Those programs all call a class static member function to get a db connection setting. The class was coded like this
class DbSetting {
public:
static string* getDbSettings();
};
string* DbSetting::getDbSettings() {
string* settings = new string[4];
settings[0] = "dbname";
settings[1] = "server";
settings[2] = "username";
settings[3] = "password";
return settings;
}
In each program main() function, it will call this static function like this,
int main(int argc, char* argv[]) {
string* dbSettings = DbSetting::getDbSettings();
//dbSettings is used to construct a db connection string
return 0;
}
The dbSettings is used to construct a db connection string. However, it wasn't being "delete" (e.g. "delete[] dbSettings"). My question is that is it a potential memory 开发者_JAVA百科leak issue? Such usage exists in many other legacy c++ programs as well. I am confused about it. Hope someone can give me an answer. Thank you!
It is indeed a memory leak. It's a somewhat minor one, since your data needs to stay alive to the end of the program anyway, and at program termination it'll be cleaned up - but it'll cause false positives on memory leak detectors, so it's often a good idea to properly clean up anyway; if you let yourself rely on OS cleanup, when you really do need to diagnose a memory leak, you'll find you have hundreds of false positives to sort through! It'll also be really hard to refactor the code to be part of a larger system where it may be started and stopped multiple times in the same process.
The simplest way to avoid this is by using vector
:
std::vector<string> DbSetting::getDbSettings() {
std::vector<string> settings(4);
settings[0] = "dbname";
settings[1] = "server";
settings[2] = "username";
settings[3] = "password";
return settings;
}
int main(int argc, char* argv[]) {
std::vector<string> dbSettings = DbSetting::getDbSettings();
//dbSettings is used to construct a db connection string
return 0;
}
vector
will automatically clean up the memory used by the string array inside it when it is destroyed when you return from main. It also has a number of very convenient features that raw arrays don't - eg, it keeps track of array size, and can automatically resize the array if you add new elements using push_back
.
Basically the answer is yes. You should delete[]
the strings.
If this method is only called from the main() method, at least the leaking memory will not become bigger but remain at 4*sizeof(string)
+ the amount of memory reserved for the string data which is usually not a problem in practice. The OS will take care of the leak at exit. You should still delete[]
it for style reasons and because others might use such methods more often. If they just copy and paste such code, you soon get leaks that matter!
It'd be better approach if you pass the result of getDbSettings()
via reference parameter:
void DbSetting::getDbSettings(std::vector<std::string> &result) {
result.clear();
result.push_back("dbname");
result.push_back("server");
result.push_back("username");
result.push_back("password");
}
int main(int argc, char* argv[]) {
std::vector<std::string> dbSettings;
DbSetting::getDbSettings(dbSettings);
return 0;
}
Benefits are obvious: no memory allocation tracks required. Also there are less temporary objects used in order to pass the result back from the function. On returning std::vector<std::string>
temporary array will be copied back when function ends (in case of disabled RVO). It'd be more sensitive on larger amount of data returned, but its good practice to do this always.
Yes it is a memory leak. It is always a good practice to use delete[] after using new(). You can use smart pointer to avoid memory leaks.
精彩评论