5

This is an analogue to another question, anyway I am looking for a platform specific way to do this if it exists on iOS.

Developing for Apple platform means non-Apple based toolset is usually not well applicable. So I wish to find platform native way to do this. Because simple Google search gave me this(heap command), I'm sure that there's an API function too.

I am looking for this only for debug build assertion to detect the case of deleting stack-allocated object. So it's enough to know where the address is pointing - stack or heap. So performance, version compatibility, internal API or any quality concerns doesn't matter. (maybe testing on simulator also can be an option) But I think this is not that heavy operation if stack is completely separated from heap.

I tagged C++, but API in any other language is also fine if it is applicable from C++.

trincot
  • 317,000
  • 35
  • 244
  • 286
eonil
  • 83,476
  • 81
  • 317
  • 516
  • 1
    possible duplicate: http://stackoverflow.com/questions/17814140/static-and-dynamic-memory-allocation-of-objects-in-c – Borgleader Jul 23 '13 at 23:34
  • @Borgleader I wrote this question because there's no *generic* way to do this, but *platform specific* is possible to exist. I saw several people are mentioning MS Windows specific API for this, but no for iOS yet. – eonil Jul 23 '13 at 23:36
  • 1
    check the answer by Mats Petersson it might be of use to you. – Borgleader Jul 23 '13 at 23:38
  • Won't deleting a not-`new`ed pointer crash anyway? Why do you need a separate assertion? – Carl Norum Jul 23 '13 at 23:39
  • @CarlNorum (I wish I understood you comment correctly) Yeah it crashes when I delete it, but at the moment, it's very hard to get *where* the pointer created and passed from. If I put some assertions on proper places it would be very easy to detect the location of the bug by preventing taking wrong pointer. – eonil Jul 23 '13 at 23:46
  • Is your app using multiple threads, and creating objects in one thread and destroying in another? – Mats Petersson Jul 24 '13 at 00:35
  • 1
    @Eonil: I just added a short section on "how to find the range of the stack". – Mats Petersson Jul 24 '13 at 00:39
  • @MatsPetersson Thanks for care. My program is single threaded program, and I already did it exactly as you described. It's working well now, and seem to be enough for my purpose currently. – eonil Jul 24 '13 at 01:33
  • 1
    There is possibly a design issue in your code. You should use custom allocators when "allocating" objects on the stack. Then, you won't even run into those issues you are trying to check. – CouchDeveloper Jul 26 '13 at 19:06
  • @CouchDeveloper I think I don't know the recommended pattern. Can you point me to some good text? – eonil Jul 26 '13 at 23:38
  • The basic idea is to use a custom allocator (for classes that support this, e.g. all std classes, e.g. std::string, std::vector). The custom allocator returns uninitialized storage from the stack - if available, otherwise it returns it from the heap. The allocator takes care of deallocation. For the client this all happens behind the scenes. Further reads: [stack_alloc](http://home.roadrunner.com/~hinnant/stack_alloc.html), [Question on SO](http://stackoverflow.com/questions/11648202/questions-about-hinnants-stack-allocator) – CouchDeveloper Jul 27 '13 at 07:33
  • @Econil The described approach with a custom allocator may not be sufficient to remove all your checks. However, IMHO, having the _need_ to check whether a `delete` gets a pointer argument which actually points to the stack indicates that there is a design issue elsewhere, too. – CouchDeveloper Jul 27 '13 at 07:44

1 Answers1

1

If you use the GNU GCC compiler and glibc on iOS then I believe you can use mprobe() - if it fails then the memory block is either corrupted or a stack memory block.

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

Updated post with OS portable heap detection:

Otherwise, you could make your own heap memory manager by overriding new() &delete(), record all heap memory allocations/deallocations, then add your own heap detection function; example follows:

// 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);
}