【问题标题】:How to check a pointer is pointing heap or stack memory on iOS?如何检查指针指向 iOS 上的堆或堆栈内存?
【发布时间】:2013-07-23 06:18:51
【问题描述】:

这类似于another question,无论如何我正在寻找一种特定于平台的方式来执行此操作(如果它存在于 iOS 上)。

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

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

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

【问题讨论】:

  • @Borgleader 我写了这个问题是因为没有通用 方法可以做到这一点,但平台特定 是可能存在的。我看到有几个人为此提到了 MS Windows 特定的 API,但还没有提到 iOS。
  • 检查 Mats Petersson 的答案,它可能对您有用。
  • @Eonil:我刚刚添加了一个关于“如何查找堆栈范围”的简短部分。
  • 您的代码中可能存在设计问题。在堆栈上“分配”对象时,您应该使用自定义分配器。然后,您甚至不会遇到您要检查的那些问题。

标签: c++ ios pointers heap-memory


【解决方案1】:

如果您在 iOS 上使用 GNU GCC 编译器和 glibc,那么我相信您可以使用 mprobe() - 如果它失败了,那么内存块要么损坏,要么是堆栈内存块。

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

更新了带有操作系统可移植堆检测的帖子:

否则,您可以通过覆盖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);
}

【讨论】:

  • 你应该把long改成size_t,因为long在win64上是4个字节,这样会导致冲突。
  • @Thomas1125 现在改成 size_t
猜你喜欢
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 2020-01-03
  • 2020-07-26
  • 2012-10-07
  • 2020-09-02
相关资源
最近更新 更多