Visual Studio 2017社区中C ++调试与发布版本结果的差异

问题描述 投票:-1回答:1

为什么调试模式生成的结果与发布模式生成的结果不同?

#define devicecount 4
static const size_t c_maxCount = 4; // I should actually set it to devicecount
bool bstatus[devicecount];
bool cbflag[devicecount];
bool gbflag[devicecount];
#define dpacketlength 9

HANDLE hThreadMain[c_maxCount];
HANDLE hThreadGraph, hThreadComm;

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    // This snippet for reference only
    // ...
    int i;
    mwnd p[c_maxCount];
    for (i = 0; i < c_maxCount; i++) {
        hThreadMain[i] = CreateThread(NULL, 0, MainThread, &p[i], 0, NULL);
    }
    mwnd g;
    hThreadGraph = CreateThread(NULL, 0, UpdateGraph, &g, 0, NULL);

    mwnd c;
    hThreadComm = CreateThread(NULL, 0, CommThread, &c, 0, NULL);

    // ...
}

// Following thread function has problem
DWORD WINAPI CommThread(LPVOID lParam) {
    char data[(dpacketlength+10)] = { 0 }; // added "+ 10" later
    unsigned int i;
    char pbuf[2];
    bool skip = 0;

    while (1) {
        skip = 0;
        for (i = 0; i < c_maxCount; i++) {
            //Sleep(20); // uncommenting it makes the code work
            if (bstatus[i] == 1) { // device working
                if (cbflag[i] == 0) { // data not ready
                    skip = 1; // skip, flag not set
                }
            }
        }
        //cout << ""; // uncommenting it makes the code work
        if (skip == 1) {
            continue;
        }
        cout << "."; // This is how I measure the program is progressing or not
        // Some code to follow to send data over comm
        // ...
        // assign 9 bytes to data[] (always). 2*4 (always) for 4 devices and 1 extra parameter byte. if maxCount is < 4, the corresponding bytes are zero, as initialized INSHAALLAH.
        for (i = 0; i < c_maxCount; i++) {
            // compute pbuf[]s
            data[(2 * i)] = pbuf[0];
            data[((2 * i) + 1)] = pbuf[1];
        }
        data[8] = (char)par;
        // some code that loops over data[] from data[0] to data[8] and sends bytes over comm
        // ...
        for (i = 0; i < c_maxCount; i++) {
            cbflag[i] = 0;
        }
    }
}

我已经在Win32中编写了该软件,并附带了用于调试的控制台。该代码段来自“ comm”线程。还有其他c_maxCount个“主”线程,每个线程都分配了一个cbflag[]元素。这些线程检查设备是否在线,如果在线,则它们获取数据并准备各自的全局缓冲区。完成后,它们将设置各自的cbflag[i]。在相应的cbflag[i]重置为0之前,它们不会接触缓冲区。

[还有另一个线程“ Graph”,它可以实时在屏幕上绘制图形。当设置了gbflag[]中的任何一个(对应于每个主线程)时,Graph线程进行绘制,并在绘制后重置gbflag[i]。该图在发行版本中处于冻结状态,我开始通过在代码中加入cout进行调试。显然,主线程正在无限期等待,因为在函数结束时未在此代码的第三个cbflag[]循环中重置for,因为正在对代码进行skip ped /continued。这是我发现,如果在检查cout之前放了skip,即使它打印出空字符串,代码也可以正常工作。 “工作”是指未对代码的下半部分执行skip操作。因此,现在我不能在不影响系统的情况下进行调试。另外,我尝试将消息框放在第一个for循环中,然后检查是否跳过,但是它仍然会影响代码并且开始工作。如果将c_maxCount更改为1,它将开始工作并且不会跳过。如果我取消对Sleep(20)行的注释,它将起作用并且不会跳过。但是,如果我插入代码以为coutSleep()分配一个值给变量,则它不起作用,因此不会影响行为。

我已经读过stackoverflow,在发布应用程序崩溃的情况下,它主要与数组范围有关。我增加了data[]数组,但无济于事。

我通过定期打印到标签的屏幕上来检查Graph线程中bstatus[]cbflag[]的值,两个数组的所有元素均为1。

c++ visual-c++ visual-studio-2017 release visual-studio-debugging
1个回答
0
投票

由于cbflag被一个线程修改并被另一线程读取,因此它应该是std::atomic。编译器可能会做出关于非原子全局变量(即未修改)的假设,这些变量会影响它在调试版本中未建立的发行版本。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.