я должен освободить память для «string * settings = new string [4]» в c ++ в Linux? - PullRequest
0 голосов
/ 05 октября 2011

В настоящее время я отлаживаю некоторые устаревшие программы на С ++, работающие в ОС Linux (centos 5).Все эти программы вызывают статическую функцию-член класса для получения настройки соединения с БД.Класс был закодирован следующим образом:

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 используется для создания соединения БД.строка.Однако это не было «удалить» (например, «удалить [] dbSettings»).Мой вопрос заключается в том, что это потенциальная проблема утечки памяти?Такое использование существует и во многих других старых программах на С ++.Я запутался в этом.Надеюсь, кто-нибудь может дать мне ответ.Спасибо!

Ответы [ 4 ]

2 голосов
/ 05 октября 2011

Это действительно утечка памяти.Это несколько второстепенно, так как ваши данные должны остаться в живых до конца программы в любом случае, и по завершении программы она будет очищена - но это вызовет ложные срабатывания на детекторах утечки памяти, поэтому часто это хорошая идеявсе равно правильно убирать;если вы позволите себе полагаться на очистку ОС, когда вам действительно потребуется диагностировать утечку памяти, вы обнаружите, что вам нужно разобраться с сотнями ложных срабатываний!Также будет очень трудно реорганизовать код, чтобы он стал частью более крупной системы, где он может запускаться и останавливаться несколько раз в одном и том же процессе.

Самый простой способ избежать этого - использовать 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 автоматически очистит память, используемую массивом строк внутри него, когда он будет уничтожен при возврате из main.Он также имеет ряд очень удобных функций, которых нет в необработанных массивах - например, он отслеживает размер массива и может автоматически изменять размер массива, если вы добавляете новые элементы, используя push_back.

0 голосов
/ 05 октября 2011

Да, это утечка памяти.Всегда полезно использовать delete [] после использования new ().Вы можете использовать умный указатель, чтобы избежать утечек памяти.

0 голосов
/ 05 октября 2011

Будет лучше, если вы передадите результат 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<std::string> временный массив будет скопирован обратно после завершения функции (в случае отключенного RVO). Это было бы более чувствительно при большем количестве возвращаемых данных, но рекомендуется делать это всегда.

0 голосов
/ 05 октября 2011

В основном ответ - да. Вы должны delete[] строки.

Если этот метод вызывается только из метода main (), по крайней мере утечка памяти не станет больше, но останется на 4*sizeof(string) + объем памяти, зарезервированный для строковых данных, что обычно не является проблемой на практике. ОС позаботится об утечке при выходе. Вы все еще должны delete[] это по стилевым причинам и потому, что другие могут использовать такие методы чаще. Если они просто скопируют и вставят такой код, вы скоро получите утечки, которые имеют значение!

...