User created class in MFC going out of scope???

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • manontheedge
    New Member
    • Oct 2006
    • 175

    User created class in MFC going out of scope???

    I'm having trouble using MFC in Visual Studio 6. The problem I'm having is, say I have a text box that information is typed into. Once a button is clicked, this information is passed into code in a class ( that I created and added to the project ). This works fine. Now, there's a second button, and a second text box. When that second button is clicked, the info that was sent into my code should come out ( via another function in my class ) in that second text box. It's not happening. The text box is being filled with jumbled garbage.

    One thing I did notice, is that if I perform BOTH functions inside 1 button click, it comes out fine. This makes me think that my class, my code, is going out of scope and losing it's values.

    The problem is that I need my code to retain it's values. This is the first time I've ever used MFC, and I've tried everything I can think of, but nothing is working. I've never been this frustrated, and nothing I've found addresses this. It's probably something silly I'm missing, but I need help.

    If what I'm saying isn't clear, please let me know, and I'll give more details. Any help is greatly appreciated.
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    Originally posted by manontheedge
    I'm having trouble using MFC in Visual Studio 6. The problem I'm having is, say I have a text box that information is typed into. Once a button is clicked, this information is passed into code in a class ( that I created and added to the project ). This works fine. Now, there's a second button, and a second text box. When that second button is clicked, the info that was sent into my code should come out ( via another function in my class ) in that second text box. It's not happening. The text box is being filled with jumbled garbage.
    The text is not passed into a class, it is passed into an instance of the class.

    The class is the type of the thing, the instance is the thing itself.

    Without seeing any code it sounds like you do not have an instance of your class that persists between calls to the button handlers. It sounds like you are creating the instance as an automatic variable on the stack. An instance of this sort would be destructed when the function enters resulting in the 2 button click handler functions operating on separate instances of the class.

    You need to place an instance of the class (or a pointer to an instance that is new'd) in the class that contains the button handler methods.

    Comment

    • manontheedge
      New Member
      • Oct 2006
      • 175

      #3
      It sounds like you are creating the instance as an automatic variable on the stack. An instance of this sort would be destructed when the function enters resulting in the 2 button click handler functions operating on separate instances of the class.

      You need to place an instance of the class (or a pointer to an instance that is new'd) in the class that contains the button handler methods.
      thanks for the reply,

      that is what I thought was the problem, where I was declaring the instance of my class. I'll just put some of the code up...


      this is my class ( i've stripped everything out but 2 functions to keep testing it )

      Code:
      #ifndef INFO_H
      #define INFO_H
      
      class info
      {
      
      private:
      	char* name;	
      
      public:
      	void addName( char* n );
      	char* viewNames();
      };
      
      #endif

      my project name is "book", so this is the header file for the GUI part ... the code that is bold is what i've added ... THIS is where I declare the instance of my class.

      Code:
      // bookDlg.h : header file
      //
      
      #if !defined(AFX_BOOKDLG_H__B2E13E72_531A_4911_BEA6_D9116C6D7D45__INCLUDED_)
      #define AFX_BOOKDLG_H__B2E13E72_531A_4911_BEA6_D9116C6D7D45__INCLUDED_
      
      #if _MSC_VER > 1000
      #pragma once
      #endif // _MSC_VER > 1000
      
      
      [B]#include "info.h"[/B]
      
      /////////////////////////////////////////////////////////////////////////////
      // CBookDlg dialog
      
      class CBookDlg : public CDialog
      {
      // Construction
      public:
      	CBookDlg(CWnd* pParent = NULL);	// standard constructor
      
      // Dialog Data
      	//{{AFX_DATA(CBookDlg)
      	enum { IDD = IDD_BOOK_DIALOG };
      	CString	m_first;
      	CString	m_last;
      	CString	m_email;
      	int		m_index;
      	int		m_index2;
      	[B]info i;[/B]
      	//}}AFX_DATA
      
      	// ClassWizard generated virtual function overrides
      	//{{AFX_VIRTUAL(CBookDlg)
      	protected:
      	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
      	//}}AFX_VIRTUAL
      
      	// Implementation
      protected:
      	HICON m_hIcon;
      
      	// Generated message map functions
      	//{{AFX_MSG(CBookDlg)
      	virtual BOOL OnInitDialog();
      	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
      	afx_msg void OnPaint();
      	afx_msg HCURSOR OnQueryDragIcon();
      	afx_msg void OnButton1();
      	afx_msg void OnButton3();
      	//}}AFX_MSG
      	DECLARE_MESSAGE_MAP()
      };
      
      //{{AFX_INSERT_LOCATION}}
      // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
      
      #endif // !defined(AFX_BOOKDLG_H__B2E13E72_531A_4911_BEA6_D9116C6D7D45__INCLUDED_)

      this is the definition file for the GUI part ... the code that is bold is what i've added

      Code:
      // bookDlg.cpp : implementation file
      //
      
      #include "stdafx.h"
      #include "book.h"
      [B]#include "info.h"[/B]
      #include "bookDlg.h"
      
      
      #ifdef _DEBUG
      #define new DEBUG_NEW
      #undef THIS_FILE
      static char THIS_FILE[] = __FILE__;
      #endif
      
      /////////////////////////////////////////////////////////////////////////////
      // CAboutDlg dialog used for App About
      
      <snip CAboutDlg implementation>
      
      /////////////////////////////////////////////////////////////////////////////
      // CBookDlg dialog
      
      CBookDlg::CBookDlg(CWnd* pParent /*=NULL*/)
      	: CDialog(CBookDlg::IDD, pParent)
      {
      	//{{AFX_DATA_INIT(CBookDlg)
      	m_first = _T("");
      	m_last = _T("");
      	m_email = _T("");
      	m_index = 0;
      	m_index2 = 0;
      	//}}AFX_DATA_INIT
      	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
      	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
      }
      
      <snip CBookDlg functions that are not relevent to problem>
      
      void CBookDlg::OnButton1() 
      {
      	[B]UpdateData( true );[/B]	
      	
      	[B]char temp[50];[/B]
      	[B]strcpy( temp, m_first );[/B]
      	[B]i.addName( temp );[/B]
      
      	[B]UpdateData( false );[/B]	
      }
      
      
      void CBookDlg::OnButton3()
      {
      	[B]UpdateData( true );[/B]
      	
      	[B]m_last = i.viewNames();[/B]
      	
      	[B]UpdateData( false );[/B]
      }
      m_first is the first text box, m_last is the second text box ( just to clarify ).


      hopefully, that makes it more clear. Again, I appreciate the help.
      Last edited by Banfa; May 8 '08, 10:19 AM. Reason: Snipped code not relevent to problem

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        This looks correct which suggest the error is in your implementation of class info.

        Comment

        • manontheedge
          New Member
          • Oct 2006
          • 175

          #5
          this is the declaration of my class
          Code:
          #ifndef INFO_H
          #define INFO_H
          
          class info
          {
          
          private:
          	char* name;	
          
          public:
          	void addName( char* n );
          	char* viewNames();
          };
          
          #endif

          this is the definition of the class
          Code:
          #include "stdafx.h"
          #include "info.h"
          
          void info::addName( char* n )
          {
          	name = n;
          }
          
          char* info::viewNames( )
          {
          	return name;
          }

          here is where my class is being called ...the only thing it could possibly be is the "UpdateData ", but I don't THINK that has anything to do with it (?), but again, if I call both functions of my class in "OnButton1( )" it works fine, telling me my class is okay...
          Code:
          void CBookDlg::OnButton1() 
          {
          	UpdateData( true );	
          	
          	char temp[50];
          	strcpy( temp, m_first );
          	i.addName( temp );
          
          	UpdateData( false );	
          }
          
          
          void CBookDlg::OnButton3()
          {
          	UpdateData( true );
          	
          	m_last = i.viewNames();
          	
          	UpdateData( false );
          }
          Is it possible there's some setting I've missed? Like I said before, this is my first time using MFC. I've looked over this, and messed with it for hours, and can't find a single thing wrong with it. Maybe there's something I need to do with the project settings ... that's the ONLY thing I can think of. Any ideas?

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            Nope you have an implementation problem in your class info.

            You are copying the pointer not what is pointed to, however where you are calling your instance of the class you are passing a pointer to the array temp which (as the name suggests) only exists temporarily as it is on the stack. As soon as the function exits that variable ceases to exist and the data is used for something else.

            The instance of you class is left pointing at the place temp used to exist.

            What you need to do is inside info allocate memory for storage of the supplied string using new, making sure that you don't cause any memory leaks and that you release the memory when the instance is destructed and that if the instance is reused there is enough memory for the new usage.

            This memory will persist until you release it because it is allocated from the heap not the stack.

            Comment

            • manontheedge
              New Member
              • Oct 2006
              • 175

              #7
              Banfa, thank you so much. Apparantly I'm a little more rusty on dealing with memory in C++ than I thought. I'll go back and read up on what I've forgotten. I really appreciate the help. Thank you, that was definately the problem.

              Comment

              Working...