1

I have an issue with an MFC dialog based application build with MSVC 2013. To make the main dialog accessible also during more elaborate functions, I'm using multi-threading. A click on a button in the dialog calls a "worker function" that is worked out by another thread.

Here's an excerpt of the class:

class CpiezcamDlg : public CDialogEx
{
protected:
    virtual BOOL OnInitDialog();

public:
    CWinThread *m_thread1;

    void StartSweepAndImageThread()
    {
        m_thread1 = AfxBeginThread(SweepAndImageThreadProc, this);
    }

private:
    static UINT SweepAndImageThreadProc(LPVOID pParam)
    {
        CpiezcamDlg *pThis = (CpiezcamDlg *)pParam;
        UINT nRet = pThis->DoSweepAndImage();
        return nRet;
    }

    UINT DoSweepAndImage();

    UINT16 steps;
    CString *imgs_name;
};

Clicking a button calls StartSweepAndImageThread which itself calls SweepAndImageThreadProc and finally DoSweepAndImage. In the function DoSweepAndImage, variables of the class are accessed (read and write). Amongst others, there is imgs_name. The usage is:

UINT CpiezcamDlg::DoSweepAndImage()
{
    // ...
    CString str;
    str.Format(_T("Test"));
    AddStageListText(str);

    imgs_name[i] = str;
    // ...
}

while imgs_name is initialized like

steps = 4;
imgs_name = new CString[steps];

in the OnInitDialog function.

The problem is that when pressing the mention button I receive

0xC0000005: Access violation reading location 0xFDFDFDF9.

exactly on imgs_name[i] = str;. When using a statical array, that is instead of CString *imgs_name; I define CString imgs_name[4];, everything works well. However, I very much would like to have that CString variable a dynamical one. Thanks in advance for your help!

PS: When I evaluated this in a serial way, i.e. when running the DoSweepAndImage function in the main thread, everything goes well. That's why I assume the access violation is due to the multi-threading.

@Wimmel: The loop over i in DoSweepAndImage is

for (UINT16 i = 0; i < steps; i++)
Clemens
  • 313
  • 4
  • 15
  • 2
    0xFDFDFDF9 is probably related to [0xFDFDFDFD](http://stackoverflow.com/a/127404/33499) – wimh Sep 07 '14 at 15:43
  • Could it be that `i` is less than `0` or larger than `3` on the line `imgs_name[i] = str`? – wimh Sep 07 '14 at 15:46
  • But then I would guess to not read it when pressing "`Ctrl + F5`" -- Running without debugging. Isn't it? Furthermore, it would fail also in the other instances (when not using multithreading). – Clemens Sep 07 '14 at 15:47
  • those magic numbers are related to the runtime environment (debug or release). Not whether you run with or without debugger. Although you might not see all errors without debugger. – wimh Sep 07 '14 at 15:50
  • 1
    0xFDFDFDF9 is heap guard data in debug mode. Usually when you see errors like this it means you have attempted to access beyond the edge of a heap object. Is it possible that somehow you are accessing beyond the end of the img_name array? When you define the array statically this type of guard information isn't available. So it is possible the issue still exists with a statically defined array, but the problem is hidden. By the way this question looks somewhat familiar ;-) – Michael Petch Sep 07 '14 at 16:08
  • Are you, by any chance, closing the dialog while the thread is still running? – Igor Tandetnik Sep 07 '14 at 16:10
  • The other possibility is that you somehow freed the img_array before a call to `imgs_name[i] = str` – Michael Petch Sep 07 '14 at 16:14
  • A dumb question might be. Did you initialize `CpiezcamDlg`s `steps` variable? If steps had junk in it I wonder if you ended up processing more images than you thought you were. For instance you do `steps = 4; imgs_name = new CString[steps];` to initializes. If in the function that initializes you defined `steps` as well as a local variable you wouldn't be updating the class variable. – Michael Petch Sep 07 '14 at 16:17
  • I'm not sure if this should be a comment or an answer. However: Thanks all for your tips. I learned that there might be a problem when defining `CString imgs_name[4]`, even though it's not shown when debugging. So I inspected what `CString imgs_name[4]` actually means. And I found that what I should use is `CStringArray imgs_name` and then calling `imgs_name.Add(str);` for each iteration in the loop instead. That works. See e.g. http://www.ucancode.net/Visual_C_MFC_Samples/CStringArray-CString.htm PS: The dialog isn't closed, nor is something freed before the call, and `steps` is initialize – Clemens Sep 07 '14 at 16:38
  • I'd add it as an answer to your own question. There is some etiquette in doing so. See: http://meta.stackexchange.com/questions/17845/etiquette-for-answering-your-own-question Item #3 would apply now. – Michael Petch Sep 07 '14 at 16:46
  • I must admit it still doesn't explain why the method used in your question didn't work. I look at your original code and you have img_array as a pointer to CString. You then initialize it so it happens to be a pointing to the first element in an array of CString's (which you allocate) which is completely valid. – Michael Petch Sep 07 '14 at 17:14
  • Thanks Michael, I will do so. But only after the explanation is valid: I'm not 100% sure, but to get an array of `CString`s one has to be more careful --- if the same problem if that one here applies: http://stackoverflow.com/questions/34987/how-to-declare-an-array-of-strings-in-c – Clemens Sep 07 '14 at 19:56

0 Answers0