运行时检查失败#2 C / C ++

时间:2010-07-01 19:07:19

标签: c++ c file-io wofstream

我在我的程序中遇到了一个让我有点难过的问题。我有一个工作正常的程序(它在VS 2010上工作正常,这不是我升级到.NET而且这个错误开始发生了),程序主要是c和一些c ++(我的老板HATES面向对象,因为它通常涉及打电话到图书馆,他是偏执狂微软将停止支持,如果他们的旧版本可能是一个问题,也可能必须交付给客户,因为他们中很多人是政府,他也认为这些电话会导致不必要的开销,所以我必须尽可能地避免它)然后我取消注释一个代码块(我会将这个块稍微低一些,因为它已经从原来的一个我没有被修改过一些)开始处理它得到错误“运行时检查错误#2堆栈周围”std“已损坏”其中std是wchar的ac样式字符串。

我试图通过实现一些不那么好的修复来弄清楚问题是什么,因为如果一个有效,我会知道实际问题是什么,然后有一个很好的调试基础起点。首先,我尝试增加std的大小,使其足够大,以至于我不会放入比它可以处理的更大的字符串(它的值来自列表视图中不超过3列,每个列都不能大于80个字符)虽然这让我更少地得到错误但我仍然得到它。

所以我尝试将该代码块中的std切换到msg(这与当时的std完全相同),以查看msg是否得到了相同的错误(这意味着它是由该代码块产生的)但是错误仍然出现在标准周围。

case IDC_TXT:
                    //FileSaveBox(hwnd, L"Save as...",L"Text Files (*.txt)\0*.txt\0All Files\0*.*\0",L"*.txt",wFileName);
                    FileSaveBox(hwnd, L"Save as...",L"CSV (Coma delimited) (*.csv)\0*.csv\0All Files\0*.*\0",L"*.csv",wFileName);

                        if(wcslen(wFileName)==0) return 0;

                        fin.open(wFileName);
                        if(fin.is_open())
                            val=MessageBox(hwnd,L"This file allready exists. Do you want to overwrite it?",L"Confirm Save", MB_YESNO);
                        fin.close();

                        if (val == IDNO)
                            return 0;

                        fout.open(wFileName);
                        if(!fout.is_open()) return 0;

                        /*if ((fp = _wfopen (wFileName, L"w"))==NULL)   
                        {
                            Message("Cannot Open File");
                            return 0;
                        }*/

                        _swprintf(msg,L"Some string");
                        if(im.col3)
                            wcscat(msg,L", another string");

                        fout << msg << L"\n";

                        count = ListView_GetItemCount(hlvim);
                        for(i=0;i<count;i++) 
                        {
                                ListView_GetItemText(hlvim,i,0,msg,240);
                                wcscat(msg,L", ");
                                ListView_GetItemText(hlvim,i,1,temp,80);
                                wcscat(msg,temp);
                                if(im.col3)
                                {
                                    wcscat(msg,L", ");
                                    ListView_GetItemText(hlvim,i,2,temp,80);
                                    wcscat(msg,temp);
                                }

                                fout << msg << L"\n";

                            //fprintf(fp,"%s\n",msg);
                        }
                        //fclose(fp);
                        fout.close();
                        SetFocus(hwnd);
                        return 0;

这让我觉得可能只是在std周围写了一些其他的变量,所以我用msg替换了它的所有实例后将其注释掉了(execpt表示它是一个局部变量的函数当错误发生时,它还没有被调用)但这只是导致错误出现在msg周围(实际上它也显示为函数的局部变量)。

接下来我尝试通过使用静态来声明堆上的msg而不是堆栈(因为使用new会让我的老板很讨厌现代代码)但是这只会导致以下错误:“HTZx86.exe中的0x00300030处的未处理异常:0xC0000005:访问冲突读取位置0x00300030。“并且在位置0x00300030是对外部API的调用,我无法控制。

现在,在我对代码的其他部分进行了一些不相关的修改之后,我会在std和msg的同时(有时在函数调用之后,有时在之前)随机获取堆栈,而不是在一致的基础上。我想知道是否有任何好的方法来调试这个问题,因为断点本身并没有帮助我,也不是调用堆栈(虽然我可能使用它们错了)?

Bellow是变量的声明,也是调用函数之前调用它的唯一其他位置:

声明:

int i,j,k,count,val,ntx,nrx,IsActive, rxcount;
    BOOL callsign, map2rx, rxhit;
    double f1,f2,f3;
    WCHAR str[80];
    static WCHAR msg[240];
    WCHAR temp[80];
    static short dir;
    //FILE* fp;
    std::wofstream fout;
    std::wifstream fin;
    LV_COLUMN pcol;
    LV_ITEM pit, pit2;
    static HWND hlvtx;
    static HWND hlvrx;
    static HWND hlvim;

和其他电话:

count = ExternalAPIFunction2t();
            for(i=0;i<count;i++)
            {
                ntx = _wtoi(ExternalAPIFunction1(i+1,_SP_NBTXCH));
                nrx = _wtoi(ExternalAPIFunction1(i+1,_SP_NBRXCH));
                IsActive = _wtoi(ExternalAPIFunction1(i+1,_SP_ISACTIVE));

                try
                {
                for(j=0;j<ntx && IsActive;j++)
                {
                    f1 = _wtof(ExternalAPIFunction1(i+1,_SP_TXCH01+j));
                    _swprintf(msg,L"%09.4f MHz",f1);

                    pit.mask = LVIF_TEXT|LVIF_PARAM;
                    pit.iItem = j;
                    pit.iSubItem = 0;
                    pit.lParam = j; 
                    wcscpy_s(msg,ExternalAPIFunction1(i+1,_SP_CALLSIGN));
                    wcscat_s(msg,L"_CH");
                    _itow(j+1,temp,80);
                    wcscat_s(msg,temp);
                    pit.pszText = msg;
                    ListView_InsertItem(hlvtx,&pit);
                    _swprintf(msg,L"%.4f",f1);
                    pit.mask = LVIF_TEXT;
                    pit.iSubItem = 1;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvtx,&pit);
                    f1 = _wtof(ExternalAPIFunction1(i+1,_SP_NOMINALPOWER));
                    _swprintf(msg,L"%.1f",f1);
                    pit.iSubItem = 2;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvtx,&pit);
                    _swprintf(msg,L"%f",i+1);
                    pit.iSubItem = 3;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvtx,&pit);           

                }
                }catch(std::exception &e)
                {
                    MessageBox(hwnd,(wchar_t*) e.what(),L"Error", MB_OK);
                }

                for(j=0;j<nrx && IsActive;j++)
                {
                    f1 = _wtof(ExternalAPIFunction1(i+1,_SP_RXCH01+j));
                    pit.mask = LVIF_TEXT|LVIF_PARAM;
                    pit.iItem = j;
                    pit.iSubItem = 0;
                    pit.lParam = j; 
                    wcscpy(msg,ExternalAPIFunction1(i+1,_SP_CALLSIGN));
                    wcscat(msg,L"_CH");
                    _itow(j+1,temp,10);
                    wcscat(msg,temp);
                    pit.pszText = msg;
                    ListView_InsertItem(hlvrx,&pit);
                    _swprintf(msg,L"%.4f",f1);
                    pit.mask = LVIF_TEXT;
                    pit.iSubItem = 1;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvrx,&pit);
                    f1 = _wtof(ExternalAPIFunction1(i+1,_SP_RXBANDWIDTH));
                    _swprintf(msg,L"%.2f",f1);
                    pit.iSubItem = 2;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvrx,&pit);
                    _swprintf(msg,L"%f",i+1);
                    pit.iSubItem = 3;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvrx,&pit);
                }
            }

P.S。 ExternalAPIFunction1是具有访问冲突的那个。

1 个答案:

答案 0 :(得分:1)

代码中充满了定时炸弹。这从FileSaveBox开始,您在其中传递字符串缓冲区但不告诉函数缓冲区有多长。添加大量的_swprintf,wcscpy和wcscat调用,这些调用都不会检查缓冲区是否会溢出,并且很容易解释RTC错误。

您知道如何使用wcspcy_s和wcscat_s,使其保持一致。