застрял в бесконечном цикле в освобождении памяти - PullRequest
1 голос
/ 21 октября 2011

Я попросил помочь по этому вопросу здесь Статический член, восстанавливающий память и восстанавливающийся после исключения

нижеприведенная программа предназначена для выделения памяти с использованием собственного нового оператора. Я должен выдать исключение при выделении 5-го объекта и восстановить, освободив память (странный вопрос, я знаю, но это назначение)

Я написал код здесь. распределение работает, но когда я пытаюсь вызвать delete (через опцию '2'), я застреваю в бесконечном цикле.

#include <iostream>
#include <cstdlib>

using namespace std;

class object
{
    int data;
    static int count;
    static void* allocatedObjects[5];
public:
    object() {  }
    void* operator new(size_t);
    void operator delete(void *);
    void static release();
    void static printCount()
    {
        cout << count << '\n';
    }
    ~object()
    {
        release();
    }
};

int object::count = 0;
void* object::allocatedObjects[5];

void* object::operator new(size_t size)
{
    if (count > 5)
        throw "Cannot allocate more than 5 objects!\n";
    void *p = malloc(size);
    allocatedObjects[count] = p;
    count++;
    return p;
}

void object::operator delete(void *p)
{
    free(p);
    count--;
}

void object::release()
{
    while (count > 0)
    {
        delete static_cast<object*> (allocatedObjects[count]);
    }
}

int main()
{
    object *o[10];
    int i = -1;
    char c = 1;
    while (c != '3')
    {
        cout << "Number of objects currently allocated : ";
        object::printCount();
        cout << "1. Allocate memory for object.\n";
        cout << "2. Deallocate memory of last object.\n";
        cout << "3. Exit.\n";
        cin >> c;
        if (c == '1')
        {
            try
            {
                i++;
                o[i] = new object;
            }
            catch (char* e)
            {
                cout <<e;
                object::release();
                i = 0;
            }
        }
        else if (c == '2' && i >= 0)
        {
            delete o[i];
            i--;
        }
    }
    return 0;
}

Что я делаю не так?

EDIT Я исправил проблему удаления. Избавившись от деструктора. И явно вызывает release в конце main.

Но теперь мой блок catch не является исключением. После размещения 5 объектов исключение выдается (как отслеживается отладчиком), но не перехватывается. Новые изменения в коде не влияют на связанный код.

1 Ответ

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

Бесконечный цикл происходит потому, что деструктор (~object()) вызывается раньше object::operator delete(). Ваш деструктор пытается удалить самый последний выделенный объект, который вызывает деструктор для того же объекта. operator delete() никогда не вызывается.

Я не уверен, чего достигнет allocatedObjects, и код будет работать без него. Избавьтесь также от release ().

UPDATE

ОК, поэтому существует необходимость в выпуске (обработка исключений).

Не вызывайте релиз от деструктора. Вместо этого заставьте функцию operator delete() установить запись allocatedObjects равной 0 после вызова free (зеркальное отображение operator new()). Функция release() вызывается только во время обработки исключений и обеспечивает правильное освобождение неосвобожденной памяти (т. Е. Перебирает массив allocatedObjects и free ненулевые записи, а затем устанавливает их на ноль.

...