“我必须释放内存吗?”;字符串*设置=新字符串[4]”;在c++;在linux中? 我目前正在调试Linux操作系统(CCENOS 5)中运行的一些传统C++程序。这些程序都调用一个类静态成员函数来获得db连接设置。这门课的编码是这样的 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; }
在每个程序main()函数中,它都会这样调用这个静态函数“我必须释放内存吗?”;字符串*设置=新字符串[4]”;在c++;在linux中? 我目前正在调试Linux操作系统(CCENOS 5)中运行的一些传统C++程序。这些程序都调用一个类静态成员函数来获得db连接设置。这门课的编码是这样的 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; },c++,linux,pointers,memory-leaks,C++,Linux,Pointers,Memory Leaks,在每个程序main()函数中,它都会这样调用这个静态函数 int main(int argc, char* argv[]) { string* dbSettings = DbSetting::getDbSettings(); //dbSettings is used to construct a db connection string return 0; } dbSettings用于构造db连接字符串。但是,它不是“delete”(例如“delete[]dbSe
int main(int argc, char* argv[]) {
string* dbSettings = DbSetting::getDbSettings();
//dbSettings is used to construct a db connection string
return 0;
}
dbSettings用于构造db连接字符串。但是,它不是“delete”(例如“delete[]dbSettings”)。我的问题是,这是一个潜在的内存泄漏问题吗?这样的用法也存在于许多其他的传统C++程序中。我对此感到困惑。希望有人能给我一个答案。谢谢大家! 基本上答案是肯定的。您应该
删除[]
字符串
如果仅从main()方法调用此方法,至少泄漏的内存不会变大,而是保持为
4*sizeof(string)
+为字符串数据保留的内存量,这在实践中通常不是问题。操作系统将处理出口处的泄漏。出于风格原因以及其他人可能更频繁地使用此类方法,您仍然应该删除[]
。如果他们只是复制和粘贴这样的代码,你很快就会得到泄漏的问题 这确实是内存泄漏。这是一个小问题,因为您的数据无论如何都需要在程序结束前保持活动状态,并且在程序终止时它会被清除-但是它会在内存泄漏检测器上导致误报,所以通常正确地清理是一个好主意;如果你让自己依赖操作系统清理,当你真的需要诊断内存泄漏时,你会发现你有数百个误报要处理!要将代码重构为一个更大系统的一部分,在这个系统中,代码可能会在同一个过程中多次启动和停止,这也是非常困难的
避免这种情况的最简单方法是使用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;
}
std::vector DbSetting::getDbSettings(){
标准::向量设置(4);
设置[0]=“dbname”;
设置[1]=“服务器”;
设置[2]=“用户名”;
设置[3]=“密码”;
返回设置;
}
int main(int argc,char*argv[]){
std::vector dbSettings=DbSetting::getDbSettings();
//dbSettings用于构造数据库连接字符串
返回0;
}
vector
将自动清理从main返回时被销毁的字符串数组使用的内存。它还具有许多原始数组所没有的非常方便的功能—例如,它跟踪数组大小,如果您使用push_back
添加新元素,则可以自动调整数组大小。如果您通过引用参数传递getDbSettings()
的结果,则最好采用这种方法:
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;
}
void DbSetting::getDbSettings(std::vector&result){
result.clear();
结果:推回(“dbname”);
结果。推回(“服务器”);
结果。推回(“用户名”);
结果。推回(“密码”);
}
int main(int argc,char*argv[]){
std::向量数据库设置;
DbSetting::getDbSettings(dbSettings);
返回0;
}
好处显而易见:不需要内存分配轨道。此外,用于从函数传回结果的临时对象也较少。返回时,函数结束时(在禁用RVO的情况下),将复制回临时数组。它会对返回的数据量更敏感,但最好总是这样做。是的,这是内存泄漏。在使用new()之后使用delete[]始终是一种好的做法。您可以使用智能指针来避免内存泄漏。如果您可以使用c++11,
array
将更合适。IMHO,最好重写getDbSettings,将std::vector作为参考参数返回,而不是返回值。它将减少一次对vector的冗余复制。@zabulus,当您返回在自动变量中创建的对象时,在大多数情况下,编译器可以优化掉该副本(调用者提供内存将结果放入其中,被调用者将对象构造到该区域)@bdonlan,此优化是隐式的,这是不好的thing@zabulus,这通常被认为是好的风格。特别是,C++0x通过允许(通过右值引用移动语义)接近RVO的内容(即使您正在为现有变量赋值),进一步鼓励了这一点。