2013-07-23 60 views
4

这是一个类似于another question,无论如何,我正在寻找一种特定平台的方式来做到这一点,如果它存在于iOS上。如何检查指针是否指向iOS上的堆或堆栈内存?

为Apple平台开发意味着基于非Apple的工具集通常不太适用。所以我希望找到平台原生的方式来做到这一点。因为简单的谷歌搜索给了我this(heap command),我相信也有一个API函数。

我正在寻找仅用于调试构建断言来检测删除堆栈分配对象的情况。所以知道地址指向的位置就足够了 - 堆栈或堆。因此,性能,版本兼容性,内部API或任何质量问题都无关紧要。 (也许在模拟器上测试也可以是一个选项)但是我认为如果堆栈与堆完全分离,这并不是那么繁重的操作。

我标记了C++,但如果它适用于C++,其他语言的API也可以。

+1

可能重复:http://stackoverflow.com/questions/17814140/static-and-dynamic-memory-allocation-of-objects-in-c – Borgleader

+0

@Borgleader我写了这个问题,因为有没有*通用*的方式来做到这一点,但*平台特定*可能存在。我看到有几个人提到了MS Windows的具体API,但是iOS还没有。 – Eonil

+1

查看Mats Petersson的答案,它可能对你有用。 – Borgleader

回答

1

如果使用iOS上的GNU GCC编译器和glibc那么我相信你可以使用mprobe() - 如果它失败,则该内存块已损坏或堆内存块。

http://www.gnu.org/software/libc/manual/html_node/Heap-Consistency-Checking.html

更新后与OS便携堆检测:

否则,你可以通过重写new() & delete(),记录所有的堆内存分配/释放操作使自己的堆内存管理器,然后加入您的自己的堆检测功能;例如如下:

// Untested pseudo code follows: 
// 
#include <mutex> 
#include <map> 
#include <iostream> 

std::mutex g_i_mutex; 
std::map<size_t, void*> heapList; 

void main() 
{ 
    char var1[] = "Hello"; 
    char *var2 = new char[5]; 

    if (IsHeapBlock(&var1)) 
     std::cout "var1 is allocated on the heap"; 
    else 
     std::cout "var1 is allocated on the stack"; 

    if (IsHeapBlock(var2)) 
     std::cout "var2 is allocated on the heap"; 
    else 
     std::cout "var2 is allocated on the stack"; 

    delete [] var2; 
} 

// Register heap block and call then malloc(size) 
void *operator new(size_t size) 
{ 
    std::lock_guard<std::mutex> lock(g_i_mutex); 
    void *blk = malloc(size); 
    heapList.Add((size_t)blk, blk); 
    return blk; 
} 

// Free memory block 
void operator delete(void *p) 
{ 
    std::lock_guard<std::mutex> lock(g_i_mutex); 
    heapList.erase((size_t)p); 
    free(p); 
} 

// Returns True if p points to the start of a heap memory block or False if p 
// is a Stack memory block or non-allocated memory 
bool IsHeapBlock(void *p) 
{ 
    std::lock_guard<std::mutex> lock(g_i_mutex); 
    return heapList.find((size_t)p) != heapList.end(); 
} 

void *operator new[] (size_t size) 
{ 
    return operator new(size); 
} 

void operator delete[] (void * p) 
{ 
    operator delete(p); 
} 
+0

您应该更改为size_t,因为long64在win64上长4个字节,这可能会导致冲突。 – Thomas

+0

@ Thomas1125现在更改为size_t – 2013-07-24 02:40:34