Fortunately I only found three problem cases in which a placement new was used to create an array. I fixed them by also keeping track of the raw pointer and calling free on that. Patch below, enjoy!
Another problem introduced by the compiler adding padding, is that you also need to account for that when allocating your memory. For instance if you do this:
Code: Select all
void *ptr = btAlignedAlloc(btAlignedAlloc(sizeof(Handle)*maxHandles,16);
m_pHandles = new(ptr) Handle[maxHandles];
and the compiler adds 16 bytes padding, you didn't reserve enough memory to begin with. If you then traverse through the array, the last item of the array will be out of bounds. Therefore make 100% sure you account for the padding in the btAlignedAllocInternal and btAlignedAlloc functions!
Cheers,
Martijn
Code: Select all
Index: btAxisSweep3.h
===================================================================
--- btAxisSweep3.h (revision 1223)
+++ btAxisSweep3.h (working copy)
@@ -77,9 +77,11 @@
BP_FP_INT_TYPE m_numHandles; // number of active handles
BP_FP_INT_TYPE m_maxHandles; // max number of handles
Handle* m_pHandles; // handles pool
+ void* m_pHandlesRawPtr;
BP_FP_INT_TYPE m_firstFreeHandle; // free handles list
Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries)
+ void* m_pEdgesRawPtr[3];
btOverlappingPairCache* m_pairCache;
@@ -269,8 +271,9 @@
m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize;
// allocate handles buffer and put all handles on free list
- void* ptr = btAlignedAlloc(sizeof(Handle)*maxHandles,16);
- m_pHandles = new(ptr) Handle[maxHandles];
+ m_pHandlesRawPtr = btAlignedAlloc(sizeof(Handle)*maxHandles,16);
+ m_pHandles = new(m_pHandlesRawPtr) Handle[maxHandles];
+
m_maxHandles = maxHandles;
m_numHandles = 0;
@@ -286,8 +289,8 @@
// allocate edge buffers
for (int i = 0; i < 3; i++)
{
- void* ptr = btAlignedAlloc(sizeof(Edge)*maxHandles*2,16);
- m_pEdges[i] = new(ptr) Edge[maxHandles * 2];
+ m_pEdgesRawPtr[i] = btAlignedAlloc(sizeof(Edge)*maxHandles*2,16);
+ m_pEdges[i] = new(m_pEdgesRawPtr[i]) Edge[maxHandles * 2];
}
}
//removed overlap management
@@ -310,18 +313,16 @@
#endif //DEBUG_BROADPHASE
}
-
}
template <typename BP_FP_INT_TYPE>
btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
-{
-
+{
for (int i = 2; i >= 0; i--)
{
- btAlignedFree(m_pEdges[i]);
+ btAlignedFree(m_pEdgesRawPtr[i]);
}
- btAlignedFree(m_pHandles);
+ btAlignedFree(m_pHandlesRawPtr);
if (m_ownsPairCache)
{
Index: btSimpleBroadphase.cpp
===================================================================
--- btSimpleBroadphase.cpp (revision 1223)
+++ btSimpleBroadphase.cpp (working copy)
@@ -50,8 +50,9 @@
}
// allocate handles buffer and put all handles on free list
- void* ptr = btAlignedAlloc(sizeof(btSimpleBroadphaseProxy)*maxProxies,16);
- m_pHandles = new(ptr) btSimpleBroadphaseProxy[maxProxies];
+ m_pHandlesRawPtr = btAlignedAlloc(sizeof(btSimpleBroadphaseProxy)*maxProxies,16);
+ m_pHandles = new(m_pHandlesRawPtr) btSimpleBroadphaseProxy[maxProxies];
+
m_maxHandles = maxProxies;
m_numHandles = 0;
m_firstFreeHandle = 0;
@@ -73,7 +74,7 @@
btSimpleBroadphase::~btSimpleBroadphase()
{
- btAlignedFree(m_pHandles);
+ btAlignedFree(m_pHandlesRawPtr);
if (m_ownsPairCache)
{
Index: btSimpleBroadphase.h
===================================================================
--- btSimpleBroadphase.h (revision 1223)
+++ btSimpleBroadphase.h (working copy)
@@ -59,6 +59,7 @@
int m_numHandles; // number of active handles
int m_maxHandles; // max number of handles
btSimpleBroadphaseProxy* m_pHandles; // handles pool
+ void* m_pHandlesRawPtr;
int m_firstFreeHandle; // free handles list
int m_firstAllocatedHandle;