Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > обращение к мемберам класса через указатель


Автор: zkv 23.8.2006, 07:24
пишу собсвенный хидер содержащий класс вида:
Код

class CMyClass
{
     int m_len;
    CMyClass( int len )
   {
        m_ len = len;
   }
   int GetLen()
   {
        return m_len; //ошибка возникает здесь
   }
};


потом подключив этот хидер пытаюсь произвожу следующие действия:
Код

      CMyClass *pMyClass;
      pMyClass = new CMyClass( 5 );
      cout<<pMyClass->GetLen();

Проект компилируется/линкуется без проблем, но при запуске, примерно в 50% случаев выдает ошибку: 
Unhandled exception at 0x004da816 appl.exe: 0xC0000005: Access violation reading location 0xcdcdcdd3.
в тексте программы место помечено комментарием. Если запускать  ехе-шник, то прога падает тоже в 50% случаев (притом мне кажется что вообще стабильно через раз). Если прогонять через "опасные" места прогу по шагам, то работает всегда правильно. Приложение MFC-based, среда Visual C++ 7.1.  И главное, проект уже большой очень, и если попробовать сгенерировать ошибку в другом (маленьком) проекте, то она не возникает. Делаю вывод, что у меня в проекте что-то не так smile Посмотрел, обращений по пустым указателям типа CMyClass * к  GetLen() нигде нет (но даже если бы и были, то программа падала бы независимо от того по шагам мы её или нет?). 
Внимание вопрос smile : Куда копать, чтоб найти ошибку? Важно ли что приложение MFC? Может какой нибудь макрос типа ASSERT а надо куда-нибудь прикрутить? И как вообще такое может быть что по шагам идет, а по другому нет - глюк среды? 

PS простите если не в тот форум вопрос, просто не знаю, дело в MFC или нет.

Автор: Earnest 23.8.2006, 08:56
Поставь отладочную печать (TRACE) внутри GetLen: адрес this и значение m_len.
Такое впечатление, что this левый получается. 
Между созданием объекта и вызовом GetLen есть какой-то код?
Сам по себе код выглядит невинно, скорее всего дело в другом коде.
Можно попробовать поставить точку прерывания на запись по адресу &pMyClass. Я уже не помню, как, но точно можно.
В смысле, искать, кто портит переменную.

Но начни с полного ребилда проекта. Вспомни, не переносил ли ты заголовочные файлы из одной папки в другую. Если да, то вычисти все старые хвосты.

Автор: ManiaK 23.8.2006, 08:58
zkv, точно такой код, как ты показал просто не скомпилируется. Покажи точный код, в котором такие глюки происходят.

Автор: MAKCim 23.8.2006, 09:47
Цитата

точно такой код, как ты показал просто не скомпилируется

верно

Автор: zkv 23.8.2006, 11:27
ManiaK, точно, забыл про public-и. 
совсем точный код не получится, но выше я его хм, несколько упростил, на самом деле система такая (не думал, что это принципиально):
класс в котором проблемы:
Код

class CZOOM 
{
  int wMaxVal;
  //и другие члены
public:
  CZOOM( HANDLE CamHandle )
  {
    MyExternalFunction( CamHandle,  wMaxVal ); //здесь определяется значение wMaxVal
  }
  int GetMax( )
  {
    return wMaxVal;  //тут показывает ошибку
  }
  //другие методы
};


класс в котором член - указатель на предыдущий smile 
Код

class CCam
{
  CZOOM  *pZoom;
  //и другие члены
public:
  CCam()
  {
    //...
    pZoom = NULL;
    //...
  }
  ~CCam()
  {
     //...
     if( pZoom )
       delete pZoom;
     //...
  }
  Init()
  {      
    //...
    pZoom = new CZOOM( m_Handler );
    //...
  }
  CZOOM  *GetZoomPtr()
  {
     return pZoom;
  } 
  //другие методы
};

 
 в классе моего диалога:  
Код

CMyDialog::InitDialog()   //
{
            CDialog::OnInitDialog();
             //.....
            CCam *pCam;
            pCam = new CCam;
            pCam->Init();
            //m_SZoom - control variable слайдера в моем диалоге
            m_SZoom.SetRange( 0, pCam->GetZoomPtr()->GetMax() ); //здесь единственное в проге  
                                                               //обращение к CZOOM::GetMax() 
           //...
}

Earnest спасибо, и все-таки, может ли играть роль то, что приложение MFC? Просто вспоминаю, писал проект (MFC), добавил два файла, такие:
MyClass.h   
Код

//с защитой от двойного инклуда
class MyClass
{
     MyClass();
     ~MyClass();
};

MyClass.cpp
Код

#include "MyClass.h"
MyClass::MyClass()
{
}
MyClass::~MyClass()
{
}

потом подключил хидер MyClass.h к какому то файлу проекта, вдруг вспомнил про какой то недоделанный косяк, бросился доделывать, ну думаю, кому он хидер этот помешает, пустой.
Через несколько запусков линкер стал выдавать что про операторы delete  и delete [] что типа они уже олреди определены, так как у меня эти самые операторы в проекте использовались довольно широко я естественно подумал, что у меня что то не так... Довольно долго я копался в проекте в МСДНе и яндексе,  пока не попробывал отключить этот самый пустой хидер - все заработало, решил посмотреть, получится ли еще раз такую ошибку повторить, получилось, стабильно после добавления файлов такого вида в проект,  линкер через 3-5 запусков начинал точно так же материться, причем номер проходил только с MFC приложениями. Так вот если бы сейчас кто нить спросил, "А что это у меня линкер вот так (см. выше) гонит?", то я бы естественно человеку помог бы.  Вот я и задаю вопрос в надежде, что это глюк как то связанный со средой, MFC, или еще с чем нибудь, а не с моей головой smile

Автор: ManiaK 23.8.2006, 11:32
zkv, внешне так ошибок нет вроде. Попробуй пересобери проект.

MFC язык Си++ не изменяет, потому вроде как ничего не должно быть тут. Можешь ещё попробовать из деструктора CCam убрать delete pZoom. VS очень любит мудрить с операторами delete...

Автор: zkv 23.8.2006, 14:02
вообщем, дело во внешней девайсине и/или в библиотеке к ней,  не знаю пока точно, что происходит, но это вопрос времени. Спасибо за участие. Вопрос закрыт.

ps извините что отвлек не по существу...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)