简体   繁体   English

检查指针是否指向堆上已分配的内存

[英]Check if a pointer points to allocated memory on the heap

I want to know if a pointer points to a piece of memory allocated with malloc/new. 我想知道指针是否指向一个用malloc / new分配的内存。 I realize that the answer for an arbitrary address is "No you can't" but I do think it is possible to override malloc/free and keep track of allocated memory ranges. 我意识到任意地址的答案是“不,你不能”,但我认为可以覆盖malloc / free并跟踪分配的内存范围。

Do you know a memory management library providing this specific tool? 您是否知道提供此特定工具的内存管理库?
Do you know something for production code? 你知道生产代码吗?

Valgrind is great, but it is too much instrumentation (slow) and as Will said we don't want to use Valgrind like this (making the soft crash is good enough). Valgrind很棒,但是仪表太多了(慢)并且Will说我们不想像这样使用Valgrind(使得软碰撞足够好)。
Mudflap is a very good solution, but dedicated to GCC, and sadly, a check does not simply return a boolean (see my answer below). Mudflap是一个非常好的解决方案,但是专门用于GCC,遗憾的是,检查不会简单地返回一个布尔值(请参阅下面的答案)。
Note that checking that memory writes are legal is a security issue . 请注意,检查内存写入是否合法是一个安全问题 So looking for performance is motivated. 所以寻找表现是有动力的。

A proof it probably cannot be usefully done: 证明它可能无法有效完成:

char * p1 = malloc(1);
free( p1 );
char * p2 = malloc(1);   // probably allocates same block as first malloc

Now both p1 and p2 point at same memory on heap, but only p2 is valid. 现在p1和p2都指向堆上的相同内存,但只有p2有效。

There's no standard way to do this, but various malloc debugging tools may have a way of doing it. 没有标准的方法可以做到这一点,但各种malloc调试工具可能有办法做到这一点。 For example, if you use valgrind , you can use VALGRIND_CHECK_MEM_IS_ADDRESSABLE to check this and related things 例如,如果您使用valgrind ,则可以使用VALGRIND_CHECK_MEM_IS_ADDRESSABLE来检查此相关内容

You can do this yourself, if performance is not a real issue for your application: 如果性能不是您的应用程序的真正问题,您可以自己执行此操作:

Define MyMalloc(...) and MyFree(...) in which, along with calling malloc/free, you update a (ordered)list of pairs {address -- the result of malloc, blockSize -- the amt of memory requested }. 定义MyMalloc(...)和MyFree(...),其中,与调用malloc / free一起,更新一个(有序的)对列表{address - malloc的结果,blockSize - 请求的内存的amt }。 Then when you need to check a pointer p, you look for a pair satisfying: address <= p <= address + blockSize. 然后当你需要检查指针p时,你会找到一对满足:address <= p <= address + blockSize。

Other conditions could/should be checked, if you want to actually use that pointer, this will only tell if an address is in use or not. 可以/应该检查其他条件,如果你想实际使用那个指针,这只会告诉你地址是否正在使用。

Mudflap (for gcc) seems very sweet. Mudflap (对于gcc)似乎很甜蜜。 You have to compile your soft with but it will check any wrong pointer access (heap/stack/static). 你必须编译你的软件,但它会检查任何错误的指针访问(堆/堆栈/静态)。 It is designed to work for production code with slowdown estimated between x1.5 to x5. 它设计用于生产代码,减速估计在x1.5到x5之间。 You can also disable check at read access for speedup. 您还可以禁用读取访问时的检查以获得加速。
User check can be performed using 用户检查可以使用

void __mf_check (void *ptr, __mf_size_t sz, int type, const char *location)

Calling this function results to: nothing, fork to gdb, segv or abort depending on environment parameters. 调用此函数会导致:nothing,fork to gdb,segv或abort,具体取决于环境参数。

您可以使用LD_PRELOAD,并将malloc包装在您自己的函数中。

See our CheckPointer tool, which will check every pointer access for validity. 请参阅我们的CheckPointer工具,该工具将检查每个指针访问的有效性。 Its not particularly fast, but it will catch errors that even Valgrind wont catch (eg, pointers to deallocated stack frames, etc.) 它不是特别快,但它会捕获甚至Valgrind都不会捕获的错误(例如,指向解除分配的堆栈帧的指针等)

Another answer to this question shows a case where doing pure memory range checking on pointer validity would fail to detect a problem. 这个问题的另一个答案显示了对指针有效性进行纯内存范围检查无法检测到问题的情况。 He's sort of right, in that if only have memory range addresses you can't reliably check that a reallocated block of store is misused. 他是对的,因为如果只有内存范围地址,则无法可靠地检查重新分配的存储块是否被滥用。 This is called a temporal error. 这称为时间错误。 By associating the allocation event with the memory block as well as the range, you can detect this. 通过将分配事件与内存块以及范围相关联,您可以检测到这一点。 And Checkpointer does this, and will detect the error. Checkpointer会这样做,并会检测到错误。

Memory allocations have an (virtual) address and a length. 内存分配具有(虚拟)地址和长度。

The pointer only contains the address. 指针只包含地址。

If you track the length separately, you can check its contained, eg: 如果单独跟踪长度,可以检查其包含的长度,例如:

int check_contained(const char* src,size_t srclen,const char* sub,size_t sublen) {
   return (sub >= src) && (sub+sublen < src+srclen);
}

Symbian has an AllocLen function, but there's no POSIX nor win32 equivalent. Symbian有一个AllocLen函数,但没有POSIX和win32等价物。

I did something similar, but can't remember how exactly it was coded and i don't have the code at hand. 我做了类似的事情,但不记得它是如何编码的,我手头没有代码。

But the basic idea was to override the new and delete for a base class. 但基本思想是覆盖基类的newdelete In new a static flag was set (eg bool inDynamicAlloc=true ). new的静态标志设置(例如bool inDynamicAlloc=true )。 This flag is questioned in the constructor of the base class. 在基类的构造函数中询问此标志。 When it was true, the object was allocated on the heap, on the stack otherwise. 如果是,则对象在堆上分配,否则在堆栈上。

The constructor resets the flag afterwards. 构造函数之后重置标志。

Hope this helps. 希望这可以帮助。

You could use the same techniques that a conservative garbage collector uses to determine if a pointer-like object points to the heap or not. 您可以使用保守垃圾收集器使用的相同技术来确定类似指针的对象是否指向堆。 Indeed you could probably crib the source code from bdwgc itself. 事实上,您可能会从bdwgc本身获取源代码。 This would be a non-trivial task, but it would be something you could control and port as needed. 这将是一项非常重要的任务,但它可以根据需要控制和移植。 (Much of the porting work has already been done, in fact.) (实际上,大部分移植工作已经完成。)

You can by calling malloc_size(my_ptr) in malloc/malloc.h it returns the size malloc has allocated for you for your pointer and 0 if the pointer was not allocated. 您可以通过在malloc/malloc.h调用malloc_size(my_ptr)来返回malloc为您的指针分配的大小,如果未分配指针,则返回0。 Keep in mind that malloc resizes the size of an allocated bloc to ensure that the most restrictive type variable can be dereferenced from that pointer and to align the memory. 请记住,malloc会调整已分配块的大小,以确保可以从该指针取消引用最具限制性的类型变量并对齐内存。 So if you call malloc(1) (as well as malloc(0)) malloc actually returns 16 bytes (on most machines) because the most restrictive type has a size of 16 bytes 因此,如果调用malloc(1)(以及malloc(0)),malloc实际上返回16个字节(在大多数机器上),因为最严格的类型具有16个字节的大小

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 检查指针是否指向静态分配的对象? - Check if a pointer points to statically allocated object? 堆上分配的内存大小 - Size of memory allocated on heap 分配的内存在堆栈或堆中 - Allocated memory is in the stack or heap 删除它指向的动态分配的内存后使用指针时没有错误 - No error when using pointer after deleting the dynamically allocated memory it points at 给定一个指向堆分配内存的指针,智能指针实现如何为其找到合适的释放函数? - Given a pointer to heap allocated memory, how do smart pointer implementations find the appropriate deallocation function for it? 分配&#39;this&#39;指针的内存 - Where memory for 'this' pointer allocated 将指针复制到分配的内存 - Copying a Pointer to Allocated Memory 堆上已分配内存的总线错误 - Bus error with allocated memory on a heap 当指向动态分配的内存时,指针的指针将分配什么值? - What value does a pointer to pointer get assigned when points to a dynamically allocated memory? 在C / C ++中,链表仅在堆栈中分配了头指针,而在堆中分配了其他节点。 这可能会导致内存泄漏吗? - In C/C++, linked list has only head pointer allocated in stack and other nodes allocated in heap. This may cause memory leak?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM