0

プログラムで問題が発生し、やや困惑しました。私は正常に動作していたプログラムを持っていました (VS 2010 では正常に動作していましたが、.NET にアップグレードしたのではなく、このエラーが発生し始めました) ほとんどが c であり、いくつかの c++ であるプログラム (私の上司はそれ以来、オブジェクト指向を嫌っています)通常、彼が偏執狂的なマイクロソフトのライブラリへの呼び出しを行う必要があり、それらの多くは政府のものであるため、問題になる可能性のある古いバージョンがある場合は顧客に配信する必要があり、これらの呼び出しが原因であると彼は考えています不必要なオーバーヘッドなので、可能な限り回避する必要があります) 次に、コード ブロックのコメントを外し (コメントを外した元のブロックからいくつか変更されているため、このブロックを少し下に投稿します)、作業を開始し、エラー "

あまり良くない修正をいくつか実装することで、問題が何であるかを理解しようとしました.1つが機能する場合、実際の問題が何であるかがわかり、デバッグのための適切な出発点が得られるからです. 最初に、stdのサイズを大きくして、処理できるよりも大きな文字列を入れないようにしました(値は、リストビューから3つ以下の列から取得されますが、それぞれはできません80 文字を超える必要があります)、これによりエラーが発生する頻度が減りましたが、それでもエラーが発生しました。

そのため、そのコード ブロックの std を msg (当時の std とまったく同じ) に切り替えて、msg が同じエラー (そのコード ブロックによって生成されたことを意味します) を取得したかどうかを確認しましたが、エラーは引き続き発生しました。約std。

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 の周りにエラーが表示されました (実際には、関数のローカル変数としても表示されます)。

次に、static を使用して、スタックではなくヒープで msg を宣言しようとしましたが (new を使用すると上司が非常に嫌いな最新のコードを使用するため)、次のエラーが発生するだけでした:アクセス違反読み取り場所 0x00300030." 場所 0x00300030 は、私が制御できない外部 API への呼び出しです。

コードの他の部分に無関係な変更を加えた後、std と msg の周りで同時に (関数呼び出しの後と前に) ランダムにスタック エラーを取得します。ブレークポイントだけでは役に立たず、コールスタックも役に立たないので、この問題をデバッグする良い方法があるかどうか知りたいです (ただし、間違って使用している可能性があります)。

以下は、変数の宣言と、関数が呼び出される前に呼び出される唯一の場所です。

宣言:

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);
                }
            }

アクセス違反があったのは PS ExternalAPIFunction1 でした。

4

1 に答える 1

1

コードには時限爆弾が散らばっています。これは、文字列バッファーを渡す FileSaveBox から始まりますが、関数にバッファーの長さを伝えません。大量の _swprintf、wcscpy、および wcscat 呼び出しを追加します。いずれもバッファーがオーバーランする可能性があるかどうかをチェックせず、RTC エラーは簡単に説明できます。

wcspcy_s と wcscat_s の使い方を知っているので、一貫性を持たせてください。

于 2010-07-01T19:36:58.617 に答える