Any Ideas....

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: May 2008
Posts: 8
Reputation: BAEdwards is an unknown quantity at this point 
Solved Threads: 0
BAEdwards BAEdwards is offline Offline
Newbie Poster

Any Ideas....

 
0
  #1
May 20th, 2008
I am just posting in the hopes that somenone can explain a problem I seem to be having with Turbo C++. My application basically has two forms (Form1 and Form2). Form1 is the main form and Form2 is created dynamically, as the result of a button click event, from Form1 with the following code:

  1. TForm2 *Form2 = new TForm2(this);
  2. Form2–>ShowModal();

Form2 is not included in the Auto_Create forms list under Project Options. Form2 accesses a thread object, derived from the TThread class, called Thread. A new instance of the thread is created with the following code:

  1. Thread *Thread1 = new Thread(true);

This is set running following a button click event with the following code:

  1. Thread1->Resume();

The thread updates the contents of a TMemo object named Memo1 located on Form2. The thread code looks somthing like this:

  1. void __fastcall Thread::Execute()
  2. {
  3. Synchronize(&UpdateMemo)
  4. }
  5. //---------------------------------------------------------------------------
  6. void __fastcall Thread::UpdateMemo(void);
  7. {
  8. Form2->Memo1->Lines->Add("Thread Running!");
  9. }
  10. //---------------------------------------------------------------------------

The UpdateMemo function is defined in the Thread header file as:

  1. void __fastcall Thread::UpdateMemo(void);

For some reason this code generates an access violation and I can't figure out why. If I include Form2 in the Auto_Create forms list under Project Options the thread runs (without generating errors), but doesn't update Memo1!! If I compile Form2 on its own or include Form2 in the Auto_Create forms list under Project Options and display it using the code:

  1. Form2–>ShowModal();

without creating it dynamically, the thread runs and updates Memo1 as it should. I am guessing therefore that the problem arises from the way that Form2 has been created. Any help would be much appreciated as I am really quite stumped!

Many thanks in advance.

Ben.
Last edited by BAEdwards; May 20th, 2008 at 6:19 am. Reason: Problem clarified
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 539
Reputation: thekashyap will become famous soon enough thekashyap will become famous soon enough 
Solved Threads: 50
thekashyap's Avatar
thekashyap thekashyap is offline Offline
Posting Pro

Re: Any Ideas....

 
0
  #2
May 20th, 2008
Interesting.
Do you have global and/or static variables anywhere ?
Also can you post:
- TForm2.h
- TForm2::TForm2() implementation
Are you Agile.. ?
Reply With Quote Quick reply to this message  
Join Date: May 2008
Posts: 8
Reputation: BAEdwards is an unknown quantity at this point 
Solved Threads: 0
BAEdwards BAEdwards is offline Offline
Newbie Poster

Re: Any Ideas....

 
0
  #3
May 20th, 2008
Originally Posted by thekashyap View Post
Interesting.
Do you have global and/or static variables anywhere ?
Also can you post:
- TForm2.h
- TForm2::TForm2() implementation
Here is the code from all three Units. This is not the actual project I am working on but the following code replicates the problem:

Unit1.h (Form1):
  1. //---------------------------------------------------------------------------
  2.  
  3. #ifndef Unit1H
  4. #define Unit1H
  5. //---------------------------------------------------------------------------
  6. #include <Classes.hpp>
  7. #include <Controls.hpp>
  8. #include <StdCtrls.hpp>
  9. #include <Forms.hpp>
  10. //---------------------------------------------------------------------------
  11. class TForm1 : public TForm
  12. {
  13. __published: // IDE-managed Components
  14. TButton *Button1;
  15. void __fastcall Button1Click(TObject *Sender);
  16. private: // User declarations
  17. public: // User declarations
  18. __fastcall TForm1(TComponent* Owner);
  19. };
  20. //---------------------------------------------------------------------------
  21. extern PACKAGE TForm1 *Form1;
  22. //---------------------------------------------------------------------------
  23. #endif
Unit1.cpp (Form1):
  1. //---------------------------------------------------------------------------
  2.  
  3. #include <vcl.h>
  4. #pragma hdrstop
  5.  
  6. #include "Unit1.h"
  7. #include "Unit2.h"
  8. //---------------------------------------------------------------------------
  9. #pragma package(smart_init)
  10. #pragma resource "*.dfm"
  11. TForm1 *Form1;
  12. //---------------------------------------------------------------------------
  13. __fastcall TForm1::TForm1(TComponent* Owner)
  14. : TForm(Owner)
  15. {
  16. }
  17. //---------------------------------------------------------------------------
  18. void __fastcall TForm1::Button1Click(TObject *Sender)
  19. {
  20. TForm2 *Form2 = new TForm2(this);
  21. Form2->ShowModal();
  22. }
  23. //---------------------------------------------------------------------------

Unit2.h (Form2):
  1. //---------------------------------------------------------------------------
  2.  
  3. #ifndef Unit2H
  4. #define Unit2H
  5. //---------------------------------------------------------------------------
  6. #include <Classes.hpp>
  7. #include <Controls.hpp>
  8. #include <StdCtrls.hpp>
  9. #include <Forms.hpp>
  10. #include <ComCtrls.hpp>
  11. //---------------------------------------------------------------------------
  12. class TForm2 : public TForm
  13. {
  14. __published: // IDE-managed Components
  15. TButton *Button1;
  16. TMemo *Memo1;
  17. void __fastcall Button1Click(TObject *Sender);
  18. private: // User declarations
  19. public: // User declarations
  20. __fastcall TForm2(TComponent* Owner);
  21. };
  22. //---------------------------------------------------------------------------
  23. extern PACKAGE TForm2 *Form2;
  24. //---------------------------------------------------------------------------
  25. #endif
Unit2.cpp (Form2):
  1. //---------------------------------------------------------------------------
  2.  
  3. #include <vcl.h>
  4. #pragma hdrstop
  5.  
  6. #include "Unit2.h"
  7. #include "Unit3.h"
  8. //---------------------------------------------------------------------------
  9. #pragma package(smart_init)
  10. #pragma resource "*.dfm"
  11. TForm2 *Form2;
  12.  
  13. Thread *Thread1 = new Thread(true);
  14. //---------------------------------------------------------------------------
  15. __fastcall TForm2::TForm2(TComponent* Owner)
  16. : TForm(Owner)
  17. {
  18. }
  19. //---------------------------------------------------------------------------
  20. void __fastcall TForm2::Button1Click(TObject *Sender)
  21. {
  22. Thread1->Resume();
  23. }
  24. //---------------------------------------------------------------------------

Unit3.h (Thread):
  1. //---------------------------------------------------------------------------
  2.  
  3. #ifndef Unit3H
  4. #define Unit3H
  5. //---------------------------------------------------------------------------
  6. #include <Classes.hpp>
  7. //---------------------------------------------------------------------------
  8. class Thread : public TThread
  9. {
  10. private:
  11. protected:
  12. void __fastcall Execute();
  13. public:
  14. __fastcall Thread(bool CreateSuspended);
  15. void __fastcall Thread::UpdateMemo(void);
  16. };
  17. //---------------------------------------------------------------------------
  18. #endif
Unit3.cpp (Thread):
  1. //---------------------------------------------------------------------------
  2.  
  3. #include <vcl.h>
  4. #pragma hdrstop
  5.  
  6. #include "Unit3.h"
  7. #include "Unit2.h"
  8. #pragma package(smart_init)
  9. //---------------------------------------------------------------------------
  10. __fastcall Thread::Thread(bool CreateSuspended)
  11. : TThread(CreateSuspended)
  12. {
  13. }
  14. //---------------------------------------------------------------------------
  15. void __fastcall Thread::Execute()
  16. {
  17. for (int i = 0; i <= 1000; i++)
  18. {
  19. Synchronize(&UpdateMemo);
  20. }
  21. }
  22. //---------------------------------------------------------------------------
  23. void __fastcall Thread::UpdateMemo(void)
  24. {
  25. Form2->Memo1->Lines->Add("Thread Running");
  26. }
  27. //---------------------------------------------------------------------------

Thanks,

Ben.
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 539
Reputation: thekashyap will become famous soon enough thekashyap will become famous soon enough 
Solved Threads: 50
thekashyap's Avatar
thekashyap thekashyap is offline Offline
Posting Pro

Re: Any Ideas....

 
0
  #4
May 20th, 2008
Couldn't figure anything from the code, given that it's not complete.
- How does Thread get Form2 obj?
- The access violation could be because one of the variables (Form2 or Memo1 or Lines) is uninitialized.
But can't figure out any of these from the code.
Just a couplea other thoughts:
- Check the owner's value when TForm2::TForm2(TComponent* Owner) gets called. Print out some instance specific info of TComponent that's passed. May it's different when "framework" creates it (instead of when you create it viz Form1 object)
- Other thing that I suspect more is, Memo, is an "// IDE-managed Components", so perhaps when IDE creates the Form2 (via your project settings) it takes care of init'ing it somehow?
Are you Agile.. ?
Reply With Quote Quick reply to this message  
Join Date: May 2008
Posts: 8
Reputation: BAEdwards is an unknown quantity at this point 
Solved Threads: 0
BAEdwards BAEdwards is offline Offline
Newbie Poster

Re: Any Ideas....

 
0
  #5
May 20th, 2008
Many thanks for your reply. I am afraid I am a reasonably new to C++ so you will have to excuse my ignorance.

I believe thread can locate the Form2 object by means of the include statement at the top of Unit3.cpp...
  1. #include "Unit2.h"
As to the initialisation state of Form2 and Memo I am not sure how I would go about checking this. Any direction would be much appreciated. I assumed that as objects are created on the form at design time, they would initialised in exactly the same way irrespective of whether the form they are associated with is dynamically created or automatically created when the program runs. Is this not the case?

How would I go about checking the initialisation state of Form2 and Memo1 etc so I can determine whether any difference arises as the result of the different ways of creating the form? Any further help would be much appreciated.

Many thanks,

Ben.

BTW: Although the code posted is not from the project I am working on, it is complete and should compile and replicate the problem I am experiencing.
Reply With Quote Quick reply to this message  
Join Date: May 2008
Posts: 8
Reputation: BAEdwards is an unknown quantity at this point 
Solved Threads: 0
BAEdwards BAEdwards is offline Offline
Newbie Poster

Re: Any Ideas....

 
0
  #6
May 21st, 2008
I think I've cracked it!! If I create Form2 using the following code

  1. Form2 = new TForm2(this);
  2. Form2->ShowModal();

Instead of

  1. TForm2 *Form2 = new TForm2(this);
  2. Form2->ShowModal();

the thread is now able to access the TMemo component on Form2. I'm not entirely sure why this works so if anyone has a couple of minutes spare and can offer me an explaination it would be much appreciated.

Thanks for taking the time to look at my code and offering some thoughts thekashyap . Cheers,

Ben.
Reply With Quote Quick reply to this message  
Join Date: Nov 2007
Posts: 978
Reputation: mitrmkar is just really nice mitrmkar is just really nice mitrmkar is just really nice mitrmkar is just really nice mitrmkar is just really nice 
Solved Threads: 208
mitrmkar mitrmkar is offline Offline
Posting Shark

Re: Any Ideas....

 
0
  #7
May 21st, 2008
// Your thread accesses the form via a variable named 'Form2'
// The 'Form2' variable below is local to the function and hence 
// hides the intended 'Form2' variable i.e. the correct 'Form2' does 
// not get assigned to anything.
TForm2 *Form2 = new TForm2(this);  
Form2->ShowModal();
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 539
Reputation: thekashyap will become famous soon enough thekashyap will become famous soon enough 
Solved Threads: 50
thekashyap's Avatar
thekashyap thekashyap is offline Offline
Posting Pro

Re: Any Ideas....

 
0
  #8
May 22nd, 2008
He he..
Stupid bug..
mitmkar has already explained it. Check out http://www.functionx.com/cppcli/variables/Lesson22.htm if still not clear.
PS: To catch such bugs in future, check the compiler option to increase the warning level. In Sun workshop it was +w2. RTM.
Better way is to use lint (http://www.splint.org/win32.html) though.

Totally unrelated to the problem cheat sheet for Turbo C++ found while looking for compiler guide.. http://www.sff.net/people/brian-lars...0turbo%20c.htm
Are you Agile.. ?
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 539
Reputation: thekashyap will become famous soon enough thekashyap will become famous soon enough 
Solved Threads: 50
thekashyap's Avatar
thekashyap thekashyap is offline Offline
Posting Pro

Re: Any Ideas....

 
0
  #9
May 22nd, 2008
Originally Posted by BAEdwards View Post
As to the initialisation state of Form2 and Memo I am not sure how I would go about checking this. I assumed that as objects are created on the form at design time, they would initialised in exactly the same way irrespective of whether the form they are associated with is dynamically created or automatically created when the program runs. Is this not the case?

How would I go about checking the initialisation state of Form2 and Memo1 etc so I can determine whether any difference arises as the result of the different ways of creating the form? Any further help would be much appreciated.
Couldn't help commenting: So a good practice is to initialize all your pointers to NULL (or 0) in c'tor (OR assign a valid address).
Also set it back to NULL once the object to which points to is deleted. Usually d'tor.
If you always ensure that you do this, you can always check anywhere in the code: if your pointer is NULL then it's not initialized correctly, else it's usable.

If you don't initialize it the problem is it'll contain junk value and if you're really unlucky it might even work !
Are you Agile.. ?
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the C++ Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC