我必须释放“string* settings = new string[4]”的内存吗?在 c++在Linux中?

发布于 2024-12-08 09:20:18 字数 768 浏览 0 评论 0原文

我目前正在调试一些在 Linux 操作系统(centos 5)中运行的旧版 C++ 程序。这些程序都调用类静态成员函数来获取数据库连接设置。该类的编码如下

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() 函数中,它将像这样调用这个静态函数,

int main(int argc, char* argv[]) {

    string* dbSettings = DbSetting::getDbSettings();

    //dbSettings is used to construct a db connection string

    return 0;
}

dbSettings 用于构造数据库连接字符串。然而,它并没有被“删除”(例如“delete[] dbSettings”)。我的问题是这是否是潜在的内存泄漏问题?这种用法也存在于许多其他遗留的 C++ 程序中。我对此很困惑。希望有人能给我答案。谢谢你!

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 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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无远思近则忧 2024-12-15 09:20:18

确实是内存泄漏。这是一个有点小问题,因为无论如何你的数据都需要在程序结束时保持活动状态,并且在程序终止时它会被清理 - 但它会导致内存泄漏检测器误报,所以这通常是一个好主意无论如何都要正确清理;如果您让自己依赖操作系统清理,当您确实需要诊断内存泄漏时,您会发现有数百个误报需要排序!将代码重构为更大系统的一部分也非常困难,因为它可能在同一进程中多次启动和停止。

避免这种情况的最简单方法是使用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;
}

当你从main返回时,vector会自动清理其中的字符串数组所使用的内存。它还具有许多原始数组所没有的非常方便的功能 - 例如,它跟踪数组大小,并且如果您使用 push_back 添加新元素,它可以自动调整数组大小。

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.

风渺 2024-12-15 09:20:18

基本上答案是肯定的。您应该删除[]字符串。

如果仅从 main() 方法调用此方法,至少泄漏的内存不会变大,而是保持在 4*sizeof(string) + 为字符串数据保留的内存量在实践中通常不是问题。操作系统将处理退出时的泄漏。出于风格原因,您仍然应该delete[]它,因为其他人可能会更频繁地使用此类方法。如果他们只是复制并粘贴此类代码,您很快就会发现重要的泄漏!

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!

零度℉ 2024-12-15 09:20:18

如果通过引用参数传递 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;
}

好处是显而易见的:不需要内存分配跟踪。此外,用于从函数传回结果的临时对象也较少。返回 std::vector 时,临时数组将在函数结束时复制回来(在禁用 RVO 的情况下)。它对返回的大量数据更加敏感,但始终这样做是一个好习惯。

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.

权谋诡计 2024-12-15 09:20:18

是的,这是内存泄漏。在使用 new() 之后使用 delete[] 始终是一个好习惯。您可以使用智能指针来避免内存泄漏。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文