singlepost

c++ паттерн RAII << На главную или назад  

C++ код

int* func(int* a){

int* result=(int*)malloc(sizeof(int)*200);

… … …

return result;

}

все как бы работает, но нужно ли очищать память для переменной result, и как это сделать?

просто функция эта вызывается из рекурсии много раз, и много памяти занимает программа. думаю что из за этой функции

[Добавлено модератором]
См. #24

26 ответов в теме “c++ паттерн RAII”

  1. 23
    Константин Смотритель ответил:

    Проблема навряд-ли решена. Нарушено RAII, и я уверен – нарушено и при выделении и памяти вначале. Надо очень сильно (!) бить по рукам "программистов", которые нарушают RAII в С++ – таким программистам не следует переходить на данный ЯВУ.

    Медвед, Вам уже и в #6, и позже намекнули на способ решения проблемы – auto_ptr… Вы как-то его проигнорировали?

    Для массива надо использовать Буст – shared_ptr со своим делетером или shared_array. Эти умные указатели также реализуют паттерн подсчёта ссылок (без учёта зацикливаний), что позволяет писать как в Java.

    Пример:
    typedef std:auto_ptr<CKlass> tKlass;

    {
    tKlass pInst = new CKlass(); // pInst – ссылка на объект

    pInst_>CallMethod();

    } // Объект будет автоматически уничтожен при выходе за область видимости

    Пример с массивом:
    typedef boostd:shared_array<int> aInt;

    aInt pData = new int[200]; // pData – ссылка на массив

    pData[5] = …;

    // Массив будет уничтожен по уничтожению всех ссылок

    P.S. Чтобы не тащить весь Буст, можно использовать только заголовочные файлы (для смартпоинтеров это работает) или написать свой вариант умных указателей (там немного писать).

    P.P.S В случае выделения памяти "вначале" надо использовать или shared_array, или сделать объект wrapper для массива и использовать auto_ptr (во враппере перегрузить оператор []) – хотя и обращение будет несколько неудобным по сравнению с shared_array, можно обойтись без Буста; но, вообще, с точки зрения ООП, прямого доступа к массиву быть не должно, и если правильно провести декомпозицию, тут не потребуется вообще никаких умных указателей – будет простая статическая структура, и указанных Вами пробелм просто не возникнет… Но это уже задача не программиста, а архитектора.

  2. 22
    ответил:

    решил проблему, выделив память в начале

  3. 21
    Леонид Максимов ответил:

    >> Вроде числа Фибоначчи )))

    омфг.

  4. 20
    ответил:

    дмитрий, через template опять же ограничение максимальный размер int

  5. 19
    Дмитрий Ашкадов ответил:

    template <int N>
    struct Fib {
    static const int result =Fib<N-1>::result + Fib<N-2>::result;
    };

    template <>
    struct Fib<1> {static const int result = 1;}

    template <>
    struct Fib<0> {static const int result = 1;}

    Вроде числа Фибоначчи )))

  6. 18
    ответил:

    сейчас попробую в начале выделить)

  7. 17
    Дмитрий Ашкадов ответил:

    Если твоя функция используется только внути модуля. то можно как в #3

  8. 16
    Дмитрий Ашкадов ответил:

    (int*)malloc(sizeof(int)*200) – это ЗЛО в C++. Это чудо использовать просто нельзя

    int *p = new int[200]; // и проще и нагляднее и правильно!

  9. 15
    ответил:

    задание вообще, посчитать числа фибоначчи рекурсией

  10. 14
    Дмитрий Ашкадов ответил:

    Это для очень больших чисел?

  11. 13
    Дмитрий Ашкадов ответил:

    Уже достаточно на старте выделить 2 массива ))) и более не выделять память вообще

  12. 12
    ответил:

    подскажите как? я ни разу не использовал vector

  13. 11
    Дмитрий Ашкадов ответил:

    Вот пример:

    если есть такая функция, как fopen(), которая возвращает FILE *,
    то удаление выделенной памяти осуществляет не тот, кто использует функцию, а тот, кто написал fopen(), т.е. это происходит в функции fclose()

  14. 10
    Дмитрий Ашкадов ответил:

    FILE *f = fopen();
    ….
    fclose(f);

    Выделение и удаление памяти происходит внутри библиотеки, реализующей работу с файлами на C

  15. 9
    ответил:

    это понятно
    но вот к моему примеру? как очистить память за func, после ее использования?
    или как ее нужно выделить чтобы можно было очистить?

  16. 8
    Дмитрий Ашкадов ответил:

    А что за задача то такая срекурсией?

  17. 7
    Роман Воробец ответил:

    int *p = func(..);
    … use p …
    free(p);

  18. 6
    З Ц ответил:

    добавь в конце free(result);

  19. 5
    ответил:

    в конце? после return ? а разве код после ретурна выполняется?

  20. 4
    Дмитрий Ашкадов ответил:

    Ужас! работа с памятью на разных логических уровнях – это ооочень дурной стиль.
    хотя бы auto_ptr заиспользовал бы

  21. 3
    ответил:

    в каком смысле на разных логических уровнях?

  22. 2
    Александр Lert ответил:

    Раз уж C++, а не C, то лучше использовать какой-нибудь класс для управления памятью, хотя бы vector из STL.

  23. 1
    Максим Рыбаков ответил:

    1. освобождать память нужно
    2. видимо это должен делать сторонний код, который вызывает функцию.
    int* p;
    func(p);
    free(p);
    это аналогично всяким strdup и т.п.
    только надо еще быть уверенным, чтобы никто не вызвал delete p)
    не понимаю, почему вы не используете new
    3. в случае рекурсии этот код грозит занять много памяти, я бы искал другие решения..либо другую организацию программы. к тому же, как известно, любую рекурсию можно превратить в итерацию..

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.