title: Is there *any* way to get the length of a C-style array in C++/G++?
body: <p>I've been trying to implement a lengthof (T* v) function for quite a while, so far without any success.</p>
  
  <p>There are the two basic, well-known solutions for T v[n] arrays, both of which are useless or even dangerous once the array has been decayed into a T* v pointer.</p>
  
  <pre><code>#define SIZE(v) (sizeof(v) / sizeof(v[0]))
  
  template &lt;class T, size_t n&gt;
  size_t lengthof (T (&amp;) [n])
  {
      return n;
  }
  </code></pre>
  
  <p>There are workarounds involving wrapper classes and containers like STLSoft's array_proxy, boost::array, std::vector, etc. All of them have drawbacks, and lack the simplicity, syntactic sugar and widespread usage of arrays.</p>
  
  <p>There are myths about solutions involving compiler-specific calls that are normally used by the compiler when delete [] needs to know the length of the array. According to the C++ FAQ Lite 16.14, there are two techniques used by compilers to know how much memory to deallocate: over-allocation and associative arrays. At over-allocation it allocates one wordsize more, and puts the length of the array before the first object. The other method obviously stores the lengths in an associative array. Is it possible to know which method G++ uses, and to extract the appropriate array length? What about overheads and paddings? Any hope for non-compiler-specific code? Or even non-platform-specific G++ builtins?</p>
  
  <p>There are also solutions involving overloading operator new [] and operator delete [], which I implemented:</p>
  
  <pre><code>std::map&lt;void*, size_t&gt; arrayLengthMap;
  
  inline void* operator new [] (size_t n)
  throw (std::bad_alloc)
  {
      void* ptr = GC_malloc(n);
      arrayLengthMap[ptr] = n;
      return ptr;
  }
  
  inline void operator delete [] (void* ptr)
  throw ()
  {
      arrayLengthMap.erase(ptr);
      GC_free(ptr);
  }
  
  template &lt;class T&gt;
  inline size_t lengthof (T* ptr)
  {
      std::map&lt;void*, size_t&gt;::const_iterator it = arrayLengthMap.find(ptr);
      if( it == arrayLengthMap.end() ){
          throw std::bad_alloc();
      }
      return it-&gt;second / sizeof(T);
  }
  </code></pre>
  
  <p>It was working nicely until I got a strange error: lengthof couldn't find an array. As it turned out, G++ allocated 8 more bytes at the start of this specific array than it should have. Though operator new [] should have returned the start of the entire array, call it ptr, the calling code got ptr+8 instead, so lengthof(ptr+8) obviously failed with the exception (even if it did not, it could have potentially returned a wrong array size). Are those 8 bytes some kind of overhead or padding? Can not be the previously mentioned over-allocation, the function worked correctly for many arrays. What is it and how to disable or work around it, assuming it is possible to use G++ specific calls or trickery?</p>
  
  <p><strong>Edit:</strong>
  Due to the numerous ways it is possible to allocate C-style arrays, it is not generally possible to tell the length of an arbitrary array by its pointer, just as Oli Charlesworth suggested. But it is possible for non-decayed static arrays (see the template function above), and arrays allocated with a custom operator new [] (size_t, size_t), based on an idea by Ben Voigt:</p>
  
  <pre><code>#include &lt;gc/gc.h&gt;
  #include &lt;gc/gc_cpp.h&gt;
  #include &lt;iostream&gt;
  #include &lt;map&gt;
  
  typedef std::map&lt;void*, std::pair&lt;size_t, size_t&gt; &gt; ArrayLengthMap;
  ArrayLengthMap arrayLengthMap;
  
  inline void* operator new [] (size_t size, size_t count)
  throw (std::bad_alloc)
  {
      void* ptr = GC_malloc(size);
      arrayLengthMap[ptr] = std::pair&lt;size_t, size_t&gt;(size, count);
      return ptr;
  }
  
  inline void operator delete [] (void* ptr)
  throw ()
  {
      ArrayLengthMap::const_iterator it = arrayLengthMap.upper_bound(ptr);
      it--;
      if( it-&gt;first &lt;= ptr and ptr &lt; it-&gt;first + it-&gt;second.first ){
          arrayLengthMap.erase(it-&gt;first);
      }
      GC_free(ptr);
  }
  
  inline size_t lengthof (void* ptr)
  {
      ArrayLengthMap::const_iterator it = arrayLengthMap.upper_bound(ptr);
      it--;
      if( it-&gt;first &lt;= ptr and ptr &lt; it-&gt;first + it-&gt;second.first ){
          return it-&gt;second.second;
      }
      throw std::bad_alloc();
  }
  
  int main (int argc, char* argv[])
  {
      int* v = new (112) int[112];
      std::cout &lt;&lt; lengthof(v) &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>Unfortunately due to arbitrary overheads and paddings by the compiler, there is no reliable way so far to determine the length of a dynamic array in a custom operator new [] (size_t), unless we assume that the padding is smaller than the size of one of the elements of the array.</p>
  
  <p>However there are other kinds of arrays as well for which length calculation might be possible, as Ben Voigt suggested, thus it should be possible and desirable to construct a wrapper class that can accept several kinds of arrays (and their lengths) in its constructors, and is implicitly or explicitly convertible to other wrapper classes and array types. Different lifetimes of different kinds of arrays might be a problem, but it could be solved with garbage collection.</p>