Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. problem walking all over an array

problem walking all over an array

Scheduled Pinned Locked Moved C / C++ / MFC
c++helpdata-structuresdebuggingannouncement
10 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    pblais
    wrote on last edited by
    #1

    I have a strange problem.. Well, strange for me. I have written a dll called APM_DLL.cpp and its header APM_DLL.h. I am using this dll in a dialog app calle CAPM_CPDlg.cpp and CAPM_CPDlg.h. I declare the dll in the dialog as a pointer as follows.......... In CAPM_CPDlg.h, I have the following: #include "APM_DLL.h" class CAPM_CPDlg : public CDialog { // Construction public: CAPM_CPDlg(CWnd* pParent = NULL); // standard constructor **APM_DLL *MYDLL;** Then in CAPM_CPDlg.cpp, I do the following: BOOL CAPM_CPDlg::OnInitDialog() { CDialog::OnInitDialog(); // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } **MYDLL = new APM_DLL;** Don't ask me why, I inherited this code. I have also have the following declaration inside APM_DLL.h. byte RxBuffer[256]; Anyways... in the main app, I make a call like MYDLL->GetSomething(). GetSomething() stores values in RxBuffer[0..n]. Then when I want to access this in the main app, I use MYDLL->RxBuffer[0..n]. This has worked great until this morning when I did the following in APM_DLL.h byte ROM_Buffer[100]; byte RxBuffer[256]; Now, if I put a break inside the actual dll and look at RxBuffer, it is ok. Then when I put a break in the main app right after MYDLL->GetSomething, MYDLL->RxBuffer is trashed. If I comment out the ROM_Buffer declaration, everything works fine inside the dll and out It only gets slammed if I compile the ROM_Buffer declaration. I have moved that declaration after the declaration of RxBuffer and ahead of a variable that I don't need to access from the main app. Everything seems to be working. But, I think this is only a band-aid and I am still walking over something important. By the way... if I make ROM_Buffer[200], I get the following crash error --------------------------- Microsoft Visual C++ Debug Library --------------------------- Debug Assertion Failed! Program: D:\Projects\Motorola\GS Iden APM\Software\Release\APM_CP.exe File: dbgheap.c Line: 1099 Expression: _pLastBlock == pHead For information on how your program can cause an

    Z 1 Reply Last reply
    0
    • P pblais

      I have a strange problem.. Well, strange for me. I have written a dll called APM_DLL.cpp and its header APM_DLL.h. I am using this dll in a dialog app calle CAPM_CPDlg.cpp and CAPM_CPDlg.h. I declare the dll in the dialog as a pointer as follows.......... In CAPM_CPDlg.h, I have the following: #include "APM_DLL.h" class CAPM_CPDlg : public CDialog { // Construction public: CAPM_CPDlg(CWnd* pParent = NULL); // standard constructor **APM_DLL *MYDLL;** Then in CAPM_CPDlg.cpp, I do the following: BOOL CAPM_CPDlg::OnInitDialog() { CDialog::OnInitDialog(); // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } **MYDLL = new APM_DLL;** Don't ask me why, I inherited this code. I have also have the following declaration inside APM_DLL.h. byte RxBuffer[256]; Anyways... in the main app, I make a call like MYDLL->GetSomething(). GetSomething() stores values in RxBuffer[0..n]. Then when I want to access this in the main app, I use MYDLL->RxBuffer[0..n]. This has worked great until this morning when I did the following in APM_DLL.h byte ROM_Buffer[100]; byte RxBuffer[256]; Now, if I put a break inside the actual dll and look at RxBuffer, it is ok. Then when I put a break in the main app right after MYDLL->GetSomething, MYDLL->RxBuffer is trashed. If I comment out the ROM_Buffer declaration, everything works fine inside the dll and out It only gets slammed if I compile the ROM_Buffer declaration. I have moved that declaration after the declaration of RxBuffer and ahead of a variable that I don't need to access from the main app. Everything seems to be working. But, I think this is only a band-aid and I am still walking over something important. By the way... if I make ROM_Buffer[200], I get the following crash error --------------------------- Microsoft Visual C++ Debug Library --------------------------- Debug Assertion Failed! Program: D:\Projects\Motorola\GS Iden APM\Software\Release\APM_CP.exe File: dbgheap.c Line: 1099 Expression: _pLastBlock == pHead For information on how your program can cause an

      Z Offline
      Z Offline
      Zac Howland
      wrote on last edited by
      #2

      Chances are the problem is in the dll code since you are not doing any heap allocations in this code. I take it that APM_DLL is a class that is exposed from the dll (that is, it should have AFX_EXT_CLASS or __declarspec(dllexport) prior to the class name)? That being the case, what is it trying to do? The code relating to your GetSomething call would be helpful to debug your problem. If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

      P 2 Replies Last reply
      0
      • Z Zac Howland

        Chances are the problem is in the dll code since you are not doing any heap allocations in this code. I take it that APM_DLL is a class that is exposed from the dll (that is, it should have AFX_EXT_CLASS or __declarspec(dllexport) prior to the class name)? That being the case, what is it trying to do? The code relating to your GetSomething call would be helpful to debug your problem. If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

        P Offline
        P Offline
        pblais
        wrote on last edited by
        #3

        wellllllll... I had all of what you wanted typed in here and i accidently clicked on one of the stupid adverts in the left collum and lost it all... If you send me your phone number at pblais@comcast.net, I can call you with all the details... Thanks

        D 1 Reply Last reply
        0
        • P pblais

          wellllllll... I had all of what you wanted typed in here and i accidently clicked on one of the stupid adverts in the left collum and lost it all... If you send me your phone number at pblais@comcast.net, I can call you with all the details... Thanks

          D Offline
          D Offline
          David Crow
          wrote on last edited by
          #4

          pblais wrote:

          If you send me your phone number at pblais@comcast.net, I can call you with all the details...

          Are you serious? Why would you even consider calling Zac on the phone? Post your Q&A here so that everyone can contribute and benefit.


          "The largest fire starts but with the smallest spark." - David Crow

          "Judge not by the eye but by the heart." - Native American Proverb

          1 Reply Last reply
          0
          • Z Zac Howland

            Chances are the problem is in the dll code since you are not doing any heap allocations in this code. I take it that APM_DLL is a class that is exposed from the dll (that is, it should have AFX_EXT_CLASS or __declarspec(dllexport) prior to the class name)? That being the case, what is it trying to do? The code relating to your GetSomething call would be helpful to debug your problem. If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

            P Offline
            P Offline
            pblais
            wrote on last edited by
            #5

            Ok... David.. I'll retype the whole thing again In the header file for the main dialog app, I have the following code: **#include "APM_Driver.h"** ///////////////////////////////////////////////////////////////////////////// // CAPM_CPDlg dialog class CAPM_CPDlg : public CDialog { // Construction public: CAPM_CPDlg(CWnd* pParent = NULL); // standard constructor **APM_Driver *MYDLL;** In the main cpp file for the dialog app, I have the following code: ///////////////////////////////////////////////////////////////////////////// // CAPM_CPDlg message handlers BOOL CAPM_CPDlg::OnInitDialog() { CDialog::OnInitDialog(); // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon **MYDLL = new APM_Driver;** In the dll header file I have the following code: // APM_Driver.h: interface for the APM_Driver class. // #if !defined(AFX_APM_Driver_H__C456738C_8198_48CC_8DE2_25874D70899F__INCLUDED_) #define AFX_APM_Driver_H__C456738C_8198_48CC_8DE2_25874D70899F__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 **#include "APM_exportheader.h"** . . . class APM_API APM_Driver { public: APM_Driver(); virtual ~APM_Driver(); char GetGetSomething(); **byte ROM_Buffer[100]; _<----BAD LINE_ byte RxBuffer[256];** byte TxBuffer[256]; . . . }; #endif // !defined(AFX_APM_Driver_H__C456738C_8198_48CC_8DE2_25874D70899F__INCLUDED_) in APM_exportheader.h, I have the following code: // The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the EXPORT_FUNCTIONS // symbol defined on the command line. this symbol should not be defined on any project // that uses this DLL. This way any other project whose source files include this file see // EXPORT_FUNCTIONS functions as being i

            Z 1 Reply Last reply
            0
            • P pblais

              Ok... David.. I'll retype the whole thing again In the header file for the main dialog app, I have the following code: **#include "APM_Driver.h"** ///////////////////////////////////////////////////////////////////////////// // CAPM_CPDlg dialog class CAPM_CPDlg : public CDialog { // Construction public: CAPM_CPDlg(CWnd* pParent = NULL); // standard constructor **APM_Driver *MYDLL;** In the main cpp file for the dialog app, I have the following code: ///////////////////////////////////////////////////////////////////////////// // CAPM_CPDlg message handlers BOOL CAPM_CPDlg::OnInitDialog() { CDialog::OnInitDialog(); // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon **MYDLL = new APM_Driver;** In the dll header file I have the following code: // APM_Driver.h: interface for the APM_Driver class. // #if !defined(AFX_APM_Driver_H__C456738C_8198_48CC_8DE2_25874D70899F__INCLUDED_) #define AFX_APM_Driver_H__C456738C_8198_48CC_8DE2_25874D70899F__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 **#include "APM_exportheader.h"** . . . class APM_API APM_Driver { public: APM_Driver(); virtual ~APM_Driver(); char GetGetSomething(); **byte ROM_Buffer[100]; _<----BAD LINE_ byte RxBuffer[256];** byte TxBuffer[256]; . . . }; #endif // !defined(AFX_APM_Driver_H__C456738C_8198_48CC_8DE2_25874D70899F__INCLUDED_) in APM_exportheader.h, I have the following code: // The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the EXPORT_FUNCTIONS // symbol defined on the command line. this symbol should not be defined on any project // that uses this DLL. This way any other project whose source files include this file see // EXPORT_FUNCTIONS functions as being i

              Z Offline
              Z Offline
              Zac Howland
              wrote on last edited by
              #6

              Despite the fact that there are a few less than desirable lines of code in there (that is, if the person who originally wrote it was in a code review with me, they wouldn't be enjoying it at the moment), there really doesn't seem to be anything out of the ordinary going on (especially with reference to the heap). My guess is that there are a couple things likely causing your problem: 1) Somewhere, a string operation (sprintf, printf, sscanf, etc) is being used with the wrong type. After a while, your stack gets blown up and overruns your heap (which is where you notice the problem). and/or 2) Somewhere a block of memory is being placed on the heap (your Dll class maybe), and at some point is being deleted by someone else, but the pointer is never null'ed, so you end up accessing invalid memory. You won't notice a major problem with that until you go to access a section in that memory that has been reallocated for something else (which will make your DLL class look like it is trashed, when in reality it is trying to trash something else). To debug this, I would start commenting out sections of code to get down to a bare minimal application that works completely. Then, slowly uncomment a section at a time and see when you notice the problem. It is a slow process, but will likely be the most effective in this case. If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

              P 1 Reply Last reply
              0
              • Z Zac Howland

                Despite the fact that there are a few less than desirable lines of code in there (that is, if the person who originally wrote it was in a code review with me, they wouldn't be enjoying it at the moment), there really doesn't seem to be anything out of the ordinary going on (especially with reference to the heap). My guess is that there are a couple things likely causing your problem: 1) Somewhere, a string operation (sprintf, printf, sscanf, etc) is being used with the wrong type. After a while, your stack gets blown up and overruns your heap (which is where you notice the problem). and/or 2) Somewhere a block of memory is being placed on the heap (your Dll class maybe), and at some point is being deleted by someone else, but the pointer is never null'ed, so you end up accessing invalid memory. You won't notice a major problem with that until you go to access a section in that memory that has been reallocated for something else (which will make your DLL class look like it is trashed, when in reality it is trying to trash something else). To debug this, I would start commenting out sections of code to get down to a bare minimal application that works completely. Then, slowly uncomment a section at a time and see when you notice the problem. It is a slow process, but will likely be the most effective in this case. If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                P Offline
                P Offline
                pblais
                wrote on last edited by
                #7

                to 0 to 255. If I don't compile ROM_Buffer then MYDLL->RxBuffer contains 0,1,2,3...255. If I make ROM_Buffer[3] then MYDLL->RxBuffer contains 205,205,205,0,1,2,3... but RxBuffer is still correct. So, you can see MYDLL->RxBuffer got shifted by the size of ROM_Buffer and the first n values were trashed by 205. I see this when I put a break in the main dialog right after the line.... MYDLL = new APM_Driver; in the on initdialog function Once again.. thanks for the help Zac Pierre

                Z 1 Reply Last reply
                0
                • P pblais

                  to 0 to 255. If I don't compile ROM_Buffer then MYDLL->RxBuffer contains 0,1,2,3...255. If I make ROM_Buffer[3] then MYDLL->RxBuffer contains 205,205,205,0,1,2,3... but RxBuffer is still correct. So, you can see MYDLL->RxBuffer got shifted by the size of ROM_Buffer and the first n values were trashed by 205. I see this when I put a break in the main dialog right after the line.... MYDLL = new APM_Driver; in the on initdialog function Once again.. thanks for the help Zac Pierre

                  Z Offline
                  Z Offline
                  Zac Howland
                  wrote on last edited by
                  #8

                  pblais wrote:

                  char data_1[] = {1,1,12,0}; char i_loop1 = 0; for(i_loop1 = 0; i_loop1 <= data_1[1] + 1; i_loop1++) data_1[3] ^= data_1[i_loop1];

                  This isn't the best way to initialize an element of an array (nor declare one actually). It likely isn't the cause of your problem, but very well could be if you ever changed the size of the array. A better way to write it would be: // declare the actual array size // go ahead and initialize data_1[3] to correct value: // 0 ^ 1 = 1 // 1 ^ 1 = 0 // 0 ^ 12 = 12 char data_1[4] = {1, 1, 12, 12}; It is more efficient and decreases the chance for an error to sneak in the code. For your second issue, if the next area in memory is getting trashed when you change the size of the array, look for something that is assuming a memory location (since this is a hardware simulation, I wouldn't be surprised to see a few). Also look for code similar the the segment above that writes to something out of bounds when dealing with the ROM_Buffer of a different size. If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                  P 1 Reply Last reply
                  0
                  • Z Zac Howland

                    pblais wrote:

                    char data_1[] = {1,1,12,0}; char i_loop1 = 0; for(i_loop1 = 0; i_loop1 <= data_1[1] + 1; i_loop1++) data_1[3] ^= data_1[i_loop1];

                    This isn't the best way to initialize an element of an array (nor declare one actually). It likely isn't the cause of your problem, but very well could be if you ever changed the size of the array. A better way to write it would be: // declare the actual array size // go ahead and initialize data_1[3] to correct value: // 0 ^ 1 = 1 // 1 ^ 1 = 0 // 0 ^ 12 = 12 char data_1[4] = {1, 1, 12, 12}; It is more efficient and decreases the chance for an error to sneak in the code. For your second issue, if the next area in memory is getting trashed when you change the size of the array, look for something that is assuming a memory location (since this is a hardware simulation, I wouldn't be surprised to see a few). Also look for code similar the the segment above that writes to something out of bounds when dealing with the ROM_Buffer of a different size. If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                    P Offline
                    P Offline
                    pblais
                    wrote on last edited by
                    #9

                    Zac Howland wrote:

                    For your second issue, if the next area in memory is getting trashed when you change the size of the array, look for something that is assuming a memory location (since this is a hardware simulation, I wouldn't be surprised to see a few). Also look for code similar the the segment above that writes to something out of bounds when dealing with the ROM_Buffer of a different size.

                    Hi again Zac... I've been playing around since I posted.... By the way thanks for the help on the first part... Anyways... The array below ROM_Buffer (RxBuffer) is affected but not really any code is run In the main dialog: MYDLL = new APM_Driver; bTestVal = DUT->RxBuffer[1]; **<------BREAK ONE HERE** Then in the APM_Driver.cpp file: ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// APM_Driver::APM_Driver() { baud_rate = 19200; SelectComms(); } APM_Driver::~APM_Driver() { delete comms1; } void APM_Driver::SelectComms() { int i_c; // comms1 = new CCommsDriver1; for(i_c = 0; i_c <=255; i_c++) RxBuffer[i_c] = unsigned char (i_c); for(i_c = 0; i_c <=255; i_c++) TxBuffer[i_c] = unsigned char (i_c); i_c = 1; **<------BREAK TWO HERE** } As you can see comms1 = new CCommsDriver1; has been commented out. SO the only code that is executed are the two small loops that initialize RxBuffer and TxBuffer to 0->255. Yet when I break the code at BREAK TWO, both buffers are ok but when I stop at BREAK ONE, MYDLL->RxBuffer is trashed. Thanks Pierre

                    Z 1 Reply Last reply
                    0
                    • P pblais

                      Zac Howland wrote:

                      For your second issue, if the next area in memory is getting trashed when you change the size of the array, look for something that is assuming a memory location (since this is a hardware simulation, I wouldn't be surprised to see a few). Also look for code similar the the segment above that writes to something out of bounds when dealing with the ROM_Buffer of a different size.

                      Hi again Zac... I've been playing around since I posted.... By the way thanks for the help on the first part... Anyways... The array below ROM_Buffer (RxBuffer) is affected but not really any code is run In the main dialog: MYDLL = new APM_Driver; bTestVal = DUT->RxBuffer[1]; **<------BREAK ONE HERE** Then in the APM_Driver.cpp file: ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// APM_Driver::APM_Driver() { baud_rate = 19200; SelectComms(); } APM_Driver::~APM_Driver() { delete comms1; } void APM_Driver::SelectComms() { int i_c; // comms1 = new CCommsDriver1; for(i_c = 0; i_c <=255; i_c++) RxBuffer[i_c] = unsigned char (i_c); for(i_c = 0; i_c <=255; i_c++) TxBuffer[i_c] = unsigned char (i_c); i_c = 1; **<------BREAK TWO HERE** } As you can see comms1 = new CCommsDriver1; has been commented out. SO the only code that is executed are the two small loops that initialize RxBuffer and TxBuffer to 0->255. Yet when I break the code at BREAK TWO, both buffers are ok but when I stop at BREAK ONE, MYDLL->RxBuffer is trashed. Thanks Pierre

                      Z Offline
                      Z Offline
                      Zac Howland
                      wrote on last edited by
                      #10

                      Its hard to say. Nothing in the code you've shown sticks out as a potential problem. Your best bet is to start commenting out code in your application code (not the dll) to get to a point where absolutely everything "works" (that is, no memory problems), and then to slowly umcomment blocks until you see the problem. With these types of issues, sometimes that is the only way to track it down. If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups