Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在没有bool包装的情况下检查指针是否有效_C++_Pointers - Fatal编程技术网

C++ 如何在没有bool包装的情况下检查指针是否有效

C++ 如何在没有bool包装的情况下检查指针是否有效,c++,pointers,C++,Pointers,可能重复: 如何在没有附加包装器或额外内存的情况下检查指针是否有效? “有效”是指我没有删除它,或者我可以访问它或它已分配 我正在使用VS\Windows。此有效检查仅在Windows中签入(VS),以下是功能: #pragma once //ptrvalid.h __inline bool isValid(void* ptr) { if (((uint)ptr)&7==7) return false; char _prefix; __try {

可能重复:

如何在没有附加包装器或额外内存的情况下检查指针是否有效? “有效”是指我没有删除它,或者我可以访问它或它已分配


我正在使用VS\Windows。

此有效检查仅在Windows中签入(VS),以下是功能:

#pragma once
//ptrvalid.h
__inline bool isValid(void* ptr) {
    if (((uint)ptr)&7==7)
        return false;
    char _prefix;
    __try {
        _prefix=*(((char*)ptr)-1);
    } __except (true) {
        return false;
    }
    switch (_prefix) {
    case 0:    //Running release mode with debugger
    case -128: //Running release mode without debugger
    case -2:   //Running debug mode with debugger
    case -35:  //Running debug mode without debugger
        return false;
        break;
    }
    return true;
}
用法:

#include <stdio.h>
#include "ptrvalid.h"

void PrintValid(void* ptr) {
    if (isValid(ptr))
        printf("%d is valid.\n",ptr);
    else
        printf("%d is not valid.\n",ptr);
}

int main() {
    int* my_array=(int*)malloc(4);
    PrintValid(my_array);
    PrintValid((void*)99);
    free(my_array);
    PrintValid(my_array);
    my_array=new int[4];
    PrintValid(my_array);
    delete my_array;
    PrintValid(my_array);
    getchar();
}
函数说明:(它的作用)

如果地址有效\内存起始点,则在实际检查之前检查函数。 之后,他检查该进程是否可以到达该内存的前缀(如果捕获异常,如果不能),最后一项检查是检查在任何模式下删除该内存的前缀。(调试\无调试模式\发布模式) 如果函数通过了所有这些检查,则返回true。

如果“您没有删除该内存,或者该内存已分配,或者至少您可以访问该内存”,则指针有效。因此,我建议:

  • 跟踪已分配的内存。如果此指针不在这些块中,则表示您没有分配它

  • 删除指针或释放内存时,请将其从列表中删除。这样,你也可以检查你没有删除它

  • 尝试访问它。如果您无法访问它,则它无效

  • 如果它通过了这些测试,它就是有效的

  • 我不是开玩笑。正确的方法是精确定义“有效”的含义,并精确测试指针是否满足这些条件


    <>但实际上,这并不是C++的实现方式。无论你的潜在问题是什么,都可能有更好的解决方法。

    没有标准或可移植的方法。你的问题假设的“有效”的定义是什么?@ArmenTsirunyan我在下面回答了这个问题。因为这个函数应该是FAQ。@DavidSchwartz的意思是你没有删除它,或者这个内存被分配了,或者至少你可以访问那个内存。你不能这样做,你也不应该这样做。现在如果我想使用:)我在new delete和malloc free上测试了它,并且只在windows上测试过。稍后我会查一下tcmalloc。我从来没听说过。我只是想指出,没有标准的方法来做这件事。这样做依赖于分配器的实现细节,因此它永远不会是可移植的。不过,很高兴看到如何在windows上使用VS.
    char数组[]={-128,10};char*p=&数组[1];打印有效(p)=>错误<代码>结构X{double d;字符数组[10];};X;PrintValid(&x.array[7])=>错误。可能还有其他误报/误报。这段代码的主要问题是,您似乎已经从一些测试中获得了关于前面字节值的“事实”,而这些测试并没有告诉您关于一般情况的任何信息。对于调试模式,在分配的块之前和之后确实有特定的字节值(请参阅),但是对于发布模式,这些字节可以是任何内容,您不能依赖它们是任何特定内容。另外,还有一个bug:操作符优先级意味着测试
    ((uint)ptr)和7==7
    实际上测试
    ((uint)ptr)和(7==7)
    。检查列表中的指针是否很重(我正在创建脚本语言),并且我提到我不希望指针有额外的数据。(可以是并行列表等)@MessyCode:如果检查列表很繁重,请对其进行优化。例如,您可以使用Boost的模板。我不明白为什么您不希望指针包含其他数据,因为您的问题专门要求提供其他数据(指针是否有效)。我在没有其他数据的情况下进行了询问。但我想我可以回答我的问题。(可能在下面搜索)
    764776 is valid.
    99 is not valid.
    764776 is not valid.
    774648 is valid.
    774648 is not valid.