Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Исключения и профилактика утечек памяти. 
:(
    Опции темы
makavelly
Дата 9.4.2012, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



На c++ не пишу, но возникла необходимость. Допустим, есть такой код:
Код

  MyImporter * importer = new MyImporter();
  myObject = importer->ReadFile(sourceFileName);
  
  if ( myObject == NULL )
    ThrowException("Failed to import object!");

  delete importer;

Как я понимаю, при возникновении исключительной ситуации (5-я строка), подчистить за собой не получится. Как обычно в c++ решают такие ситуации? Например, в Delphi это можно оформить как try - finally - end. Разместив удаление объекта в finally ... end можно получить почти 100% гарантию уничтожения объекта. 
И еще вопрос... Есть ли в MS VC Express 2008 какой-нибудь механизм, позволяющий отслеживать утечки памяти?
PM MAIL   Вверх
Amp
Дата 9.4.2012, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 886
Регистрация: 17.2.2009

Репутация: нет
Всего: 17



Создать объект на стэке, использовать умные указатели,  измазать код в BOOST_SCOPE_EXIT/BOOST_SCOPE_EXIT_END и т.п.
PM MAIL   Вверх
boostcoder
Дата 9.4.2012, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 20
Всего: 110



Цитата(makavelly @  9.4.2012,  16:56 Найти цитируемый пост)
Как обычно в c++ решают такие ситуации?

RAII.

тогда код записывается так:
Код

  boost::shared_ptr<MyImporter> importer(new MyImporter);
  myObject = importer->ReadFile(sourceFileName);
  
  if ( myObject == NULL )
    ThrowException("Failed to import object!");


PM WWW   Вверх
makavelly
Дата 9.4.2012, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Я наслышан о boost - массивный инструмент, можно обойтись без него?
Почитал про RAII, возникло несколько вопросов. C++ поддерживает этот принцип?
Хотелось бы еще уточнить по поводу области видимости. Пример функции (видел нечто подобное в чужом коде):
Код

void DoSomeProcessing(const char * fileName)
{
    MyImporter importer;
    myObject = importer.ReadFile(fileName);

    if ( myObject == NULL )
        ThrowException("Failed to import object!");

    /*  do something with myObject  */

}

Получается, что когда заканчивается выполнение DoSomeProcessing() importer выходит из области видимости и ресурсы будут освобождены? Если эта функция будет вызвана повторно, мы будем иметь дело с новым объектом importer? А если DoSomeProcessing() будет принадлежать классу? 
Вопросы, конечно, кажутся наивными, но как по мне, C++ коварен.
PM MAIL   Вверх
azesmcar
Дата 9.4.2012, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(makavelly @  9.4.2012,  21:00 Найти цитируемый пост)
Почитал про RAII, возникло несколько вопросов. C++ поддерживает этот принцип?

Поддерживает. Из стандартных средств можно использовать std::auto_ptr

Цитата(boostcoder @  9.4.2012,  17:03 Найти цитируемый пост)
boost::shared_ptr<MyImporter> importer(new MyImporter);

применительно к данной ситуации shared_ptr - overkill smile 
Цитата(makavelly @  9.4.2012,  21:00 Найти цитируемый пост)
Получается, что когда заканчивается выполнение DoSomeProcessing() importer выходит из области видимости и ресурсы будут освобождены? Если эта функция будет вызвана повторно, мы будем иметь дело с новым объектом importer?

Да.

Цитата(makavelly @  9.4.2012,  21:00 Найти цитируемый пост)
А если DoSomeProcessing() будет принадлежать классу? 

Без разницы.

Это сообщение отредактировал(а) azesmcar - 9.4.2012, 21:08
PM   Вверх
makavelly
Дата 9.4.2012, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Благодарю за ответы, ситуация начинает понемногу проясняться.
Еще один вопрос. Допустим, я хочу, что бы объект класса MyImporter являлся членом моего класса, который осуществляет некоторые действия над ним. Я хочу, чтобы экземпляр MyImporter'a существовал все время жизни экземпляра класса-обертки. Как я понимаю, для этого следует прописать такое объявление в объявлении класса-обертки 
Код

MyImporter * importer;

В конструкторе:
Код

importer = new MyImporter();

В деструкторе:
Код

delete importer;


PM MAIL   Вверх
azesmcar
Дата 9.4.2012, 21:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



makavelly

Можно и так
Код

class X
{
public:
   useImporter() {
      importer.import();
   }
private:
   MyImporter importer;
};

PM   Вверх
makavelly
Дата 9.4.2012, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Цитата(azesmcar @ 9.4.2012,  21:25)
makavelly

Можно и так
Код

class X
{
public:
   useImporter() {
      importer.import();
   }
private:
   MyImporter importer;
};

Т.е. получается, сам факт объявления в классе
Код

MyImporter importer;

уже создает объект importer... и как я догадываюсь, во время создания экземпляра класса X. Следует ли отсюда, что при уничтожении экземпляра класса X автоматически будут освобождены ресурсы, выделенные под importer? 
PM MAIL   Вверх
azesmcar
Дата 9.4.2012, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(makavelly @  9.4.2012,  21:37 Найти цитируемый пост)
и как я догадываюсь, во время создания экземпляра класса X

 smile 

Цитата(makavelly @  9.4.2012,  21:37 Найти цитируемый пост)
Следует ли отсюда, что при уничтожении экземпляра класса X автоматически будут освобождены ресурсы, выделенные под importer?  

 smile 
PM   Вверх
boostcoder
Дата 9.4.2012, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 20
Всего: 110



Цитата(azesmcar @  9.4.2012,  21:03 Найти цитируемый пост)
применительно к данной ситуации shared_ptr - overkill

ну да. скопеда достаточно.

PM WWW   Вверх
borisbn
Дата 10.4.2012, 06:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



makavelly, и ещё один момент. Если в заголовочный файл класса-обёртки включить объект MyImporter, а не указатель на него
Код

MyImporter m_importer; // <-- так
MyImporter *m_importer; // <-- а не так

то в этот же заголовочный файл придётся включить и h-ник с объявлением MyImporter (например "importer.h"). При включении h-ника класса-обёртки в нескольких cpp-шниках "importer.h" будет компилироваться несколько раз, что увеличивает время компиляции.
Если же ты включишь в класс-обёртку указатель, то "importer.h" достаточно включить только в cpp-нике класса обёртки, а в h-нике предобъявить MyImporter
Код

class MyImporter; // предобъявление

class Wrapper {
MyImporter * my_importer;
...
};


Это сообщение отредактировал(а) borisbn - 10.4.2012, 06:42


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
makavelly
Дата 10.4.2012, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



borisbn, я видел вот такую конструкцию в *.h:
Код

#ifndef MY_H
#define MY_H

    ...
    ...
    ...

#endif

Может это для таких случаев

Хотелось бы еще уточнить. В некоторых исходниках можно встретить подобные объявления:
Код

Object mObject;
Object m_Object;

Достаточно часто такое встречается. Какая смысловая нагрузка у префикса "m"?
PM MAIL   Вверх
azesmcar
Дата 10.4.2012, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(makavelly @  10.4.2012,  10:51 Найти цитируемый пост)
borisbn, я видел вот такую конструкцию в *.h:

Это для того, чтобы при множественном включении заголовочного файла не возникало ошибок компиляции.
Еще часто используется #pragma once, который не стандартен, но тем не менее поддерживается очень многими компиляторами.

Цитата(makavelly @  10.4.2012,  10:51 Найти цитируемый пост)
Достаточно часто такое встречается. Какая смысловая нагрузка у префикса "m"? 

Указывает на то, что это member variable. Это так называемая венгерская нотация.

Это сообщение отредактировал(а) azesmcar - 10.4.2012, 10:56
PM   Вверх
borisbn
Дата 10.4.2012, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(makavelly @  10.4.2012,  10:51 Найти цитируемый пост)
Может это для таких случаев

нет. если h-ник включен в двух разных единицах трансляции (проще - в 2-х cpp-шниках), то он будет компилироваться дважды, несмотря на эти, т.н. guard'ы. А эти guird'ы нужны, чтобы в такой ситуации
Код

// 1.h
class X {};
// 2.h
#include "1.h"
// 3.h
#include "1.h"
#include "2.h"

код из 1.h не повторялся. иначе получится 2 описания класса X.

Цитата(makavelly @  10.4.2012,  10:51 Найти цитируемый пост)
. Какая смысловая нагрузка у префикса "m"? 

member of class


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
makavelly
Дата 10.4.2012, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Еще один вопрос. Прект - dll. Есть экспортируемая функция, запускающая обработку некоторых данных. Необходимо вернуть из этой функции результат в виде кода ошибки (или ее отсутствия) и времени выполнения обработки. Т.е. получается что надо вернуть адрес структуры типа:
Код

struct MyResultA
{
    unsigned int resultCode;    
    unsigned int elapsedTime;    
};

Вопрос: чревато ли возвращать адрес локальной переменной (меня это очень смущает)? Например:
Код

MYLIB_API MyResultA * DoSomethingA( ... )
{
    MyResultA ret = {0, 0};

               /*  processin data here  */

    return &ret;
}

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1013 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.