Возможная утечка памяти при возврате указателя (массива) (C ++) - PullRequest
0 голосов
/ 23 февраля 2019

Рассмотрим фрагмент кода в C ++:

int *foo() {
    int *y = new int[1000];
    return y;
}

int main() {
    int *x = new int [1000];
    x = foo();
    delete[] x;
    return 0;
}

Когда создается x, он указывает на адрес памяти.Когда вызывается foo(), создается новый указатель y, указывающий на другой адрес, но затем x устанавливается на адрес, который имел y.Поэтому, когда он удаляется, память нового адреса освобождается, но исходный адрес, который имел x, просочился.Это правильно?

Кроме того, я внес небольшое изменение во фрагмент, вызвав delete[] x перед вызовом foo(), и он все еще скомпилирован и работает:

int *foo() {
    int *y = new int[1000];
    return y;
}

int main() {
    int *x = new int [1000];
    delete[] x;
    x = foo();
    delete[] x;
    return 0;
}

Означает ли это, что япредотвратить утечку?И последний вопрос: если я не инициализирую x при объявлении, но не удаляю его преждевременно, указывает ли это на утечку памяти?Как показано ниже:

int *foo() {
    int *y = new int[1000];
    return y;
}

int main() {
    int *x;
    x = foo();
    delete[] x;
    return 0;
}

В качестве примечания, я понимаю, что использование вектора и / или уникальных указателей безопаснее, но мне любопытно, что касается функциональности приведенного выше кода, особенно того, что происходит, когдауказатель объявлен, но инициализирован позже.

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

В приведенном выше фрагменте:

int *x = new int [1000];
x = foo();
delete[] x;

Вы присвоили указатель массива на x, но затем "сжали" его, назначив ему foo ().Если бы вы работали на языке сборки мусора (или использовали умный указатель), в этом случае память была бы восстановлена.

0 голосов
/ 23 февраля 2019

Когда x создается, он указывает на адрес памяти.Когда вызывается foo (), создается новый указатель y, указывающий на другой адрес, но затем x устанавливается на адрес, который имел y.Поэтому, когда он удаляется, память нового адреса освобождается, но исходный адрес, который имел х, просочился.Это правильно?

Да.

Значит ли это, что я предотвратил утечку?

Да.

И последний вопрос: если я не инициализирую x при объявлении, но не удаляю его преждевременно, указывает ли это на утечку памяти?

Нет.

В качестве примечания, я понимаю, что использование вектора и / или уникальных указателей безопаснее

Абсолютно.Даже без них ваш код может быть lot более ясным в отношении владения памятью, так что ваш вопрос даже не возникнет, но это правда, что переключение на стандартные контейнеры / умные указатели решит проблему прямо у источника, иЯ настоятельно рекомендую это.


tl; dr: вы правы во всем до сих пор

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...