3

いくつかの関数を使用していますが、この関数は LPWSTR 型の変数を返します (wchar_t*)

デバッガーでこの変数を確認すると、「0x2e (アドレス 0x2e 範囲外)」というエラーが表示され、その変数を使用して何らかの操作を行うと、プログラムが終了しました。

呼び出された関数を変更できません。src コードがありません。

私の質問は: c/c++ 言語には、間違った変数を呼び出す前に状況をチェックする機能がありますか? try/catch ブロックを試してみましたが、役に立ちませんでした。

私の英語ですみません、助けてくれてありがとう

編集:

エラーのあるコードの断片

PCERT_EXTENSION pCe = CertFindExtension(szOID_CRL_DIST_POINTS, pCertInfo->cExtension, pCertInfo->rgExtension);
    if (pCe) {
        PCRL_DIST_POINTS_INFO pCrlDistPointsInfo = NULL;
        PCRL_DIST_POINT *pCrlDistPointsPtr = NULL;
        PCRL_DIST_POINT pCrlDistPoints = NULL;
        DWORD pdwCrlDistPoints = sizeof (CRL_DIST_POINTS_INFO);

        if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                szOID_CRL_DIST_POINTS,
                pCe->Value.pbData,
                pCe->Value.cbData,
                CRYPT_DECODE_ALLOC_FLAG,
                (PCRYPT_DECODE_PARA) NULL,
                &pCrlDistPointsInfo,
                &pdwCrlDistPoints)) {
            printf("\n\nCannot decode CRL URL.\n\n");
        }

        if (pCrlDistPointsInfo) {

            pCrlDistPointsPtr = (PCRL_DIST_POINT*) pCrlDistPointsInfo->rgDistPoint;

            if (pCrlDistPointsPtr && pCrlDistPointsInfo->cDistPoint > 0) {

                findCDP = true;
                fwprintf(pFile, L"^^"); 
                for (int i = 0; i < pCrlDistPointsInfo->cDistPoint; i++) {

                    pCrlDistPoints = &pCrlDistPointsInfo->rgDistPoint[i];

                    if (pCrlDistPoints) {

                        LPWSTR str = (LPWSTR) pCrlDistPoints->DistPointName._empty_union_.FullName.rgAltEntry->_empty_union_.pwszURL;


                        //printf("last error= 0x%08X", GetLastError());
                        fwprintf(pFile, str);//PROGRAM TERMINATED HERE!!!
                        fwprintf(pFile, L";");

                    }
                    printf("%d\n",i);
                }

            }

            free(pCrlDistPointsInfo);
        }
    }
4

3 に答える 3

4

いいえ、ありません。無効なメモリ位置を指すポインターを設定すると、その位置にあるオブジェクトへのすべてのアクセスが未定義の動作になります。発生する可能性が最も高いのは、クラッシュまたは何らかのメモリ破損です。

于 2012-12-17T08:15:10.800 に答える
3

ポインタに値がある場合0x0000002e、それは2つのことだけを意味する可能性があります。

  • それを返すコードのバグ。あなたがそれを修正できない場合、あなたは運が悪いです...
  • 未定義のポインター値、およびエラーの理由は、変更された参照パラメーターなど、他の方法で返されます。しかし、nullポインターの代わりに未定義の値を返すことは、私の本のバグとしてカウントされます。

一方、0x2eは'.'正確にはASCII文字のように聞こえますが、ポイントされた文字列ではなくポインタ値を確認していますか?

後期編集:コードを見ると、組合が関与しているようです。クラッシュの考えられる理由は、間違った組合員にアクセスしていることです。Cユニオンでは、すべてのメンバー/フィールドが同じメモリ位置にあり、オーバーラップしています。言い換えると、ユニオンは一度に1つの値しか保持できないため、ユニオン値を初期化する関数のドキュメントや、型を示す追加の変数(Cの一般的なパターンはタイプフィールドとユニオンフィールドを含む構造体を持つため)。

于 2012-12-17T08:19:36.080 に答える
1

Windows には、アドレスが正しいアドレスかどうかをチェックする機能があります。しかし...これに頼るのは悪い習慣です.ポインタが正しいアドレスを指している場合、これがあなたが望むアドレスであるという保証はないからです.

ウィンドウ内の関数は、IsBadReadPtr、IsBadWritePtr、IsBadCodePtr です。これらの関数はデバッグ コード (アサートなど) でのみ使用し、リリース実行可能ファイルでは決してこれに依存しないことを強くお勧めします。

アプリケーションが正しく設計され、正しく機能している場合は、これらの Windows 関数に依存しないでください。

于 2012-12-17T08:24:22.877 に答える