2016-04-29 2 views
-2

Я очень осторожно отношусь к утечкам памяти, поэтому мне показалось, что я проверил бы это. В следующем примере может произойти утечка памяти? Мой инстинкт кишки говорит «да».Утечка памяти в этой ситуации? Использование нового ключевого слова снова и снова

class Handler  // Class definition 
{public: 
    ~Handler(); 
    int* ptrToInts;  
}; 

Handler::~Handler() // Class destructor 
{ 
    delete[] ptrToInts; 
} 

Handler handler;  // Global object 


void aFunction() 
{ 
    handler.ptrToInts = new int[20]; 
} 


int main() 
{ 
    bool quit = false; 

    while(!quit) 
    { 
     aFunction(); 
    } 

    return 0; 
} 

Будет ли ptrToInts создавать 20 отдельных новых ints в отдельной памяти на время heapeach?

Кроме того, еще один вопрос: если бы не деструктор, освободилась бы динамически выделенная память? Видя, как будто продолжительность жизни в классе - это продолжительность программы, будет ли она очищать всю «новую» память?

Редактировать: Спасибо за ответы. Причина, по которой я прошу об этом, заключается в том, что я пытаюсь обойти вызов new и delete каждый раз, когда WndProc вызывается для Raw Input в основном, а именно, как MSDN говорит вам об этом. Кажется очень неэффективным.

+1

Если вы 'new' более чем один раз и' удалить [] 'только один раз, то да, у вас есть утечка памяти. Они должны быть сбалансированы. –

+0

Используйте инструменты (например, http://valgrind.org/), которые расскажут вам, если (и где) ваша программа имеет утечки памяти. – simpel01

+0

valgrind не работает на платформах MS Windows. – cwschmidt

ответ

6

Как только вы переназначить указатель без использования delete[] де-выделить эту выделенную память в куче, вы создаете память протечь. Это произойдет, если вы зациклируете свой aFunction(), поскольку он повторно назначает указатель каждый раз, когда он вызывается.

Что касается вашего второго вопроса, ваш деструктор будет только delete[] последним массивом, назначенным указателю.

+0

Что произойдет, если я запустил этот код? Я не осмеливаюсь запускать его на своем компьютере, но я попытался подключиться к интернету, и он остановился после того, как выбрал bad_alloc. – Zebrafish

+0

@TitoneMaurice: Это именно то, что произойдет на вашем собственном компьютере. Это совершенно безобидно. Ваша программа выйдет из строя, а затем ваша ОС вернет память. –

+0

@TitoneMaurice, система будет исчерпана для вашего процесса в течение нескольких секунд ... И это очень хорошо, что вы быстро не справились! Вам не нужны поздние сбои в ПО. – WhiZTiM

2

Только delete[] освобождает выделение памяти, которое было выделено new. И каждый раз, когда вы используете new, вам нужен a delete.

Для другого вопроса, на основе Documentation:

MyClass * p1 = new MyClass[5]; // allocates and constructs five objects

2

Да, происходит утечка памяти при вызове функции более одного раза, без явного освобождения handler.ptrToInts после каждого вызова;

void aFunction() 
{ 
    handler.ptrToInts = new int[20]; 
} 

//-----somewhere we see the caller 

while(!quit) 
    { 
     aFunction(); 
    } 

Однако это тривиальный случай обнаружения утечек ... Вы должны научиться использовать Leak detectors и static analyzers.

How do you detect/avoid Memory leaks in your (Unmanaged) code? См

+0

Спасибо, кто-то здесь просто указал мне на valgrind.org для обнаружения утечки. – Zebrafish

+0

valgrind не будет работать в вашем случае, потому что у вас бесконечный цикл в вашем 'main()'. – cwschmidt

+0

@cwschmidt, статический анализатор будет работать. - обнаружить бесконечный цикл. :-) ... Просто добавьте, где оба отказались, отладчик должен пройти :-) – WhiZTiM

1

Конечно есть утечка памяти. Вы выделяете РАСЧ в

void aFunction() 
{ 
    handler.ptrToInts = new int[20]; 
} 

без deallocating старых Интс первых, как

void aFunction() 
{ 
    delete [] handler.ptrToInts; 
    handler.ptrToInts = new int[20]; 
} 

будет делать.

Вызов aFunction() приведет к «бесконечным» выделениям памяти. И ваш деструктор, который только освобождает последние выделенные ints, даже никогда не называется.

Почему ваш обработчик не управляет собственной памятью?

Очень плохая практика распределять память за пределами вашего объекта и освобождать ее внутри или наоборот.

Почему бы не реализовать класс обработчика таким образом:

class Handler 
{ 
public: 
    Handler(); 
    ~Handler(); 
    void aMethod(); 
private: 
    int* ptrToInts;  
}; 

Handler::Handler() { 
    handler.ptrToInts = new int[20]; 
} 

Handler::~Handler() { 
    delete[] ptrToInts; 
} 

void Handler::aMethod() { 
    delete[] ptrToInts; 
    handler.ptrToInts = new int[20]; 
} 

int main() { 
    bool quit = false; 
    Handler handler; 

    while(!quit) { 
    handler.aMethod(); 
    } 
} 
Смежные вопросы