|
1
79
你不能开那张支票。您根本无法检查指针是否“有效”。你必须相信,当人们使用带指针的函数时,他们知道自己在做什么。如果它们将0x4211作为指针值传递给您,则您必须信任它指向地址0x4211。如果他们“意外”击中了一个物体,那么即使你使用了一些可怕的操作系统功能(IsValidPtr或其他什么),你仍然会陷入一个bug,不会很快失败。 开始使用空指针来表示这种情况,并告诉库的用户,如果他们无意中传递了无效指针,就不应该使用指针,说真的:) |
|
|
2
42
这里有三种简单的方法可以让Linux下的C程序反省它运行的内存状态,以及为什么这个问题在某些上下文中有合适的复杂答案。
在Microsoft Windows下,在Process Status API(也在NUMA API中)下记录了QueryWorkingSetx函数。 |
|
|
3
30
防止因调用方发送无效指针而导致崩溃是一种很好的方法,可以使沉默的bug很难找到。 对于使用API的程序员来说,通过崩溃而不是隐藏代码来获得一条清晰的消息,即他的代码是伪造的,这不是更好吗? |
|
|
4
28
在Win32/64上,有一种方法可以做到这一点。尝试读取指针并捕获失败时将引发的SEH异常。如果它没有抛出,那么它是一个有效的指针。 但是,这个方法的问题是,它只返回是否可以从指针读取数据。它不能保证类型安全或任何数量的其他不变量。一般来说,这种方法除了说“是的,我可以在现在已经过去的时间里读取内存中的特定位置”之外,没有其他用处。 简而言之,不要这样做;) 陈雷蒙(Raymond Chen)就这一主题发表了一篇博文: http://blogs.msdn.com/oldnewthing/archive/2007/06/25/3507294.aspx |
|
|
5
16
哎呀,没办法。您应该在释放内存后始终将指针设置为NULL,以避免出现这种情况。 |
|
|
6
8
返回:
可能有比open()[可能是access]更好的系统调用可供使用,因为这有可能导致实际的文件创建代码路径,以及后续的关闭要求。 |
|
|
7
7
关于这个问题的答案,在这个问题上有点夸张:
我的建议是远离他们,有人已经发布了以下内容: http://blogs.msdn.com/oldnewthing/archive/2007/06/25/3507294.aspx http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx (“IsBadXxxPtr实际上应该被称为crashprogrammandomy”)。 如果API的用户发送坏数据,让它崩溃。如果问题是传递的数据直到稍后才被使用(这使得查找原因变得更加困难),请添加一个调试模式,在该模式下,字符串等将记录在条目中。如果他们是坏的,这将是显而易见的(并且可能崩溃)。如果这种情况经常发生,那么将您的API移出进程并让它们崩溃API进程而不是主进程可能是值得的。 |
|
|
8
5
首先,我看不出有任何必要试图保护自己不受故意试图造成撞车的来电者的伤害。他们可以通过自己尝试通过无效指针进行访问来轻松实现这一点。还有很多其他的方法——它们可以覆盖内存或堆栈。如果您需要防止这种情况,那么您需要在单独的进程中运行,使用套接字或其他IPC进行通信。 我们编写了很多软件,允许合作伙伴/客户/用户扩展功能。不可避免地,任何错误都会首先报告给我们,因此能够轻松地在插件代码中显示问题是很有用的。此外,还存在安全问题,一些用户比其他用户更受信任。 根据性能/吞吐量要求和可信度,我们使用了许多不同的方法。从最喜欢的:
在大多数情况下,使用内存池非常容易,而且不必效率低下。如果您首先分配数据,那么对照分配的值检查指针就很简单了。您还可以存储分配的长度,并在数据前后添加“magic”值,以检查有效的数据类型和数据溢出。 |
|
|
9
5
我非常赞同你的问题,因为我自己的立场几乎相同。我很欣赏很多回复所说的,它们是正确的——提供指针的例程 无法提供有效的指针。在我的例子中,几乎无法想象他们会破坏指针-但是如果他们 如果管理得当,崩溃的将是我的软件,而我将受到指责:-( 我的要求不是在细分故障后继续—这很危险—我只想在终止之前报告客户发生的情况,以便他们能够修复代码,而不是责备我! 这就是我发现如何(在Windows上)执行此操作的方法: http://www.cplusplus.com/reference/clibrary/csignal/signal/
现在这个 出现 |
|
|
10
2
对于一般情况下,指针的有效性没有C++测试的规定。很明显,可以假设NULL(0x00000000)是不好的,各种编译器和库喜欢在这里或那里使用“特殊值”以简化调试(例如,如果我在visual studio中看到指针显示为0xcecece,我知道我做错了什么)但事实是,由于指针只是内存中的一个索引,仅仅通过查看指针来判断它是否是“正确”的索引几乎是不可能的。 您可以使用dynamic_cast和RTTI执行各种技巧,以确保指向的对象是您想要的类型,但它们都要求您首先指向有效的对象。 如果您想确保您的程序能够检测到“无效”指针,那么我的建议是:在创建时立即将您声明的每个指针设置为NULL或有效地址,并在释放指针指向的内存后立即将其设置为NULL。如果您对此非常认真,那么检查NULL就是您所需要的。 |
|
|
11
2
在使用之前和之后将指针设置为NULL是一种很好的技术。如果你管理一个类内的指针(例如字符串),那么C++中很容易做到这一点:
|
|
|
12
2
|
|
|
13
1
没有任何可移植的方法可以做到这一点,在特定的平台上实现这一点可能是困难的,也可能是不可能的。在任何情况下,您都不应该编写依赖于这种检查的代码——首先不要让指针接受无效值。 |
|
|
14
1
正如其他人所说,您无法可靠地检测到无效指针。考虑无效指针可能需要的一些表单:
您可能有一个指向有效内存之外某处的指针。有效内存的组成取决于系统的运行时环境如何设置地址空间。在Unix系统上,它通常是一个虚拟地址空间,从0开始,一直到一些兆字节。在嵌入式系统上,它可能非常小。无论如何,它可能不会从0开始。如果您的应用程序恰好在管理器模式或等效模式下运行,那么您的指针可能引用真实地址,该地址可能会也可能不会使用真实内存进行备份。 您可以有一个指向有效内存中某个地方的指针,甚至在数据段、bss、堆栈或堆中,但不指向有效对象。它的一个变体是在对象发生错误之前,用于指向有效对象的指针。这种情况下的坏事包括释放、内存损坏或指针损坏。 您可能有一个完全非法的指针,例如被引用对象的指针具有非法对齐方式。 当考虑基于段/偏移的体系结构和其他奇数指针实现时,问题变得更严重。好的编译器和明智的类型使用通常会对开发人员隐藏这类事情,但是如果您想揭开面纱,试图智胜操作系统和编译器开发人员,那么,您可以,但是没有一种通用的方法可以处理您可能遇到的所有问题。
|
|
15
1
一般来说,这是不可能做到的。这里有一个特别糟糕的案例:
您正在强制运行时系统错误地解释内存位,但在这种情况下它不会崩溃,因为这些位都是有意义的。这是语言设计的一部分(请使用
|
|
|
16
1
令人难以置信的是,你能在上面的文章中读到多少误导性的信息。。。 甚至在微软的msdn文档中,IsBadPtr也被禁止。哦,好吧,我更喜欢使用应用程序而不是崩溃。即使术语工作可能不正确(只要最终用户可以继续使用应用程序)。 通过谷歌搜索,我还没有找到任何适用于windows的有用示例——找到了一个适用于32位应用程序的解决方案, 但我还需要支持64位应用程序,所以这个解决方案不适合我。
下面的代码可以检测指针是否有效,您可能需要添加一些空检查:
这是从指针得到的类名——我认为它应该足以满足您的需要。 我仍然担心的一件事是指针检查的性能——在上面的代码snipet中,已经有3-4个API调用在进行——对于时间关键型应用程序来说,这可能是一种过度杀伤力。 如果有人可以测量指针检查开销,例如C/托管/C++调用,那就更好了。 |
|
17
1
在公共API中接受任意指针作为输入参数不是一个很好的策略。最好使用“纯数据”类型,如整数、字符串或结构(当然,我指的是包含纯数据的经典结构;正式来说,任何东西都可以是结构)。 为什么?因为正如其他人所说,没有标准的方法可以知道你是否得到了一个有效的指针或一个指向垃圾的指针。
你能再检查一下吗?在这种情况下,我所做的是为指针指向的类型定义一个不变量,并在得到它时调用它(在调试模式下)。至少在不变量失败(或崩溃)时,您知道传递了一个错误的值。
|
|
|
18
1
函数必须是静态的、独立的或某个类的静态方法。 要在只读上进行测试,请复制本地缓冲区中的数据。 若要在不修改内容的情况下测试写入,请将其重写。 您只能测试第一个/最后一个地址。 如果指针无效,控制将传递给“doSomething”, 只是不要使用任何需要析构函数的东西,比如CString。 |
|
|
19
1
在Windows上,我使用以下代码:
|
|
|
20
1
本文 MEM10-C. Define and use a pointer validation function 表示在某种程度上可以进行检查,特别是在Linux操作系统下。
|
|
|
21
0
|
|
|
22
0
|
|
|
23
0
从技术上讲,您可以覆盖运算符 刚出现的 删去 但是:
a) 那个地址的内存不足 分配 b) 那个地址的内存 是 开始 阵列) 是 开始 对象地址 预期 类型 要旨 |
|
|
24
0
在C++中没有办法进行检查。如果其他代码向您传递无效指针,您应该怎么做? 你应该撞车。 为什么?查看此链接: http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx |
|
|
25
0
接受答复的附录: 假设指针只能包含三个值——0、1和-1,其中1表示有效指针,-1表示无效指针,-0表示另一个无效指针。您的指针 NULL,所有值的可能性相同?1/3. 现在,去掉有效的案例,因此对于每个无效的案例,您有一个50:50的比率来捕获所有错误。看起来不错吧?对4字节指针进行缩放。有2^32或4294967294个可能的值。其中,只有一个值是正确的,一个值是空的,您仍然会看到4294967292其他无效的情况。重新计算:您对(4294967292+1)个无效案例中的1个进行了测试。在大多数实际情况下,概率为2.xe-10或0。这就是空检查的无效性。 |
|
|
26
0
你知道,一个新的驱动程序(至少在Linux上)能够做到这一点可能不会那么难写。
|
|
|
27
0
如果它们不工作-下一个windows update将修复它? 如果它们不能在概念级工作,函数可能会从windows api中完全删除。 MSDN文档声称它们是被禁止的,其原因可能是应用程序进一步设计的缺陷(例如,通常您不应该默默地吃无效的指针——当然,如果您负责整个应用程序的设计),以及指针检查的性能/时间。 但是你不应该因为一些博客而声称它们不起作用。 在我的测试应用程序中,我已经验证了它们是否有效。 |
|
|
28
0
这些链接可能会有所帮助 _CrtIsValidPointer 验证指定的内存范围是否对读取和写入有效(仅限调试版本)。 http://msdn.microsoft.com/en-us/library/0w1ekd5e.aspx _crtcheck存储器 http://msdn.microsoft.com/en-us/library/e73x0s4b.aspx |
|
29
0
Peeter Joos的回答很好。以下是一种“官方”方式:
|
|
|
MaPo · Linux,设置锁定ICMP_过滤器选项 1 年前 |
|
Doohyeon Won · 内联函数上的奇怪现象?[关闭] 1 年前 |
|
|
Bobby · 复合字面值总是左值吗? 1 年前 |
|
9-Pin · C: 嵌套结构的堆栈内存分配 1 年前 |