2013-07-23 81 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