C++检查变量是否越界访问

3

我使用了一些函数,这些函数返回LPWSTR类型变量(wchar_t*)。

在调试器中查看这个变量,会显示错误“0x2e(地址0x2e越界)”,并且当我对该变量进行一些操作时,我的程序终止。

我不能更改调用的函数,因为我没有它的源代码。

我的问题是: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);
        }
    }

1
在你的问题中,“0x2e”错误是什么意思?我在调试器中查看了这个变量。 - hyde
1
这个函数的文档对返回值有何说明? - kol
1
地址0x2e越界,值未显示在标签中,我已修复。 - mgurov
顺便问一下,你是否理解C语言中指针和以0结尾的字符串(在这种情况下是宽字符字符串)的概念? - hyde
这个函数是关于从证书结构中获取CDP的函数。我只有一个证书,在这个证书上发现了问题。其他所有的证书都没有问题。我从证书结构中获取了PCRL_DIST_POINT,并在循环中使用了PCRL_DIST_POINT pCrlDistPoints pCrlDistPoints = &pCrlDistPointsInfo->rgDistPoint[i]。 LPWSTR str = (LPWSTR) pCrlDistPoints->DistPointName.empty_union.FullName.rgAltEntry->empty_union.pwszURL;str变量是不正确的。 - mgurov
显示剩余5条评论
3个回答

4

不会的。如果你设置一个指针,它指向一个无效的内存位置,对于那个位置的对象的每次访问都是未定义的行为。最有可能发生的是崩溃或某种形式的内存损坏。


3
如果一个指针的值为0x0000002e,它只可能有两种情况:
  • 返回该值的代码中存在错误。如果您无法修复此错误,则无能为力...
  • 未定义的指针值,并且错误的原因以其他方式返回,例如通过修改的引用参数。但是,将未定义的值返回而不是空指针仍然会在我的书中算作错误。

另一方面,0x2e听起来像ASCII字符,确切地说是'.',所以您确定正在查看指针值而不是指向的字符串吗?

晚些时候的编辑:查看代码,似乎涉及到联合体。崩溃的可能原因是,您正在访问联合体的错误成员。在C联合体中,所有成员/字段都位于同一内存位置,它们重叠。换句话说,联合体一次只能保存一个值,并且您需要以某种方式知道哪个值,例如从初始化联合值的函数的文档中或者通过一些额外的变量告诉类型(C中常见的模式是具有包含类型字段和联合字段的结构体)。


请查看我在问题下面的评论 - 我在那里写了一些关于函数的文本。 - mgurov
@mgurov,你的问题可能早已解决或解决了,但我还是编辑了我的答案... - hyde

1

Windows有功能来检查地址是否正确。但是...依赖这个功能是不好的实践,因为指针指向正确地址并不能保证这就是你想要的地址。

Windows中的函数包括:IsBadReadPtr、IsBadWritePtr和IsBadCodePtr。我强烈建议仅在调试代码(例如断言)中使用这些函数,并且永远不要依赖此功能在发布可执行文件中。

如果您的应用程序设计和工作正确,则永远不应该依赖这些Windows函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接