﻿# V586\. The 'Foo' function is called twice to deallocate the same resource\.

Анализатор обнаружил потенциальную ошибку повторного освобождения какого\-то ресурса\. При определённых обстоятельствах этот код может стать дефектом безопасности\.

Ресурсом может быть память, файл или, например, объект HBRUSH\.

Рассмотрим пример некорректного кода:

```cpp
float *p1 = (float *)malloc(N * sizeof(float));
float *p2 = (float *)malloc(K * sizeof(float));
...
free(p1);
free(p1);
```

В тексте программы имеется опечатка, из\-за которой дважды освобождается одна и та же область памяти\. Последствия выполнения такого кода предсказать сложно\. Возможно, программа аварийно завершит свою работу\. Или, возможно, продолжит свою работу, но возникнет утечка памяти \(memory leak\)\.

Более того, подобный код является дефектом безопасности и может привести к возникновению уязвимости\. Например, уязвимости подвержена функция 'malloc' \('dmalloc'\) Дуга Ли \(Doug Lea\), которая используется в некоторых библиотеках как 'malloc' по умолчанию\. Для возникновения уязвимости, связанной с двойным освобождением памяти, требуется несколько условий: блоки памяти, смежные с освобождаемым, не должны быть свободны, а список свободных блоков памяти должен быть пуст\. В этом случае возможно создание эксплойта\. Несмотря на то что подобные уязвимости сложно использовать из\-за необходимости специфичной конфигурации памяти, существуют реальные примеры уязвимого кода, который был успешно взломан\.

Корректный вариант:

```cpp
float *p1 = (float *)malloc(N * sizeof(float));
float *p2 = (float *)malloc(K * sizeof(float));
...
free(p1);
free(p2);
```

Иногда ошибка двойного освобождения ресурсов не является опасной:

```cpp
vector<unsigned> m_arrStack;
...
m_arrStack.clear();
m_arrBlock.clear();
m_arrStack.clear();
```

Случайно два раза очищаем массив\. Код работает правильно, но его всё равно следует посмотреть и поправить\. В процессе его изучения может выясниться, что забыли очистить другой массив\.

Корректный вариант:

```cpp
vector<unsigned> m_arrStack;
...
m_arrStack.clear();
m_arrBlock.clear();
```