Placement New for Arrays: Portability Concerns
In C , placement new allows for memory allocation at a specified address. However, its use for arrays introduces portability challenges. This article explores the issue and presents a portable solution.
It is often assumed that the pointer returned by new[] coincides with the provided address. However, the C standard (5.3.4, note 12) indicates that this may not be the case. This poses a problem when attempting to allocate a buffer for an array using placement new.
The following code demonstrates this issue:
#include <new> #include <stdio.h> class A { public: A() : data(0) {} virtual ~A() {} int data; }; int main() { const int NUMELEMENTS = 20; char* pBuffer = new char[NUMELEMENTS * sizeof(A)]; A* pA = new(pBuffer) A[NUMELEMENTS]; printf("Buffer address: %x, Array address: %x\n", pBuffer, pA); delete[] pBuffer; // Assertion failure due to heap corruption return 0; }
Examination of the memory reveals that some compilers (e.g., Visual Studio) allocate additional bytes before the array for internal bookkeeping (e.g., a count of array elements). This can lead to heap corruption.
The question arises: can we determine the overhead associated with placement new for arrays for different compilers? The goal is to find a portable solution.
Proposed Solution
Rather than using placement new on the entire array, a possible workaround is to allocate each array element individually:
int main(int argc, char* argv[]) { const int NUMELEMENTS = 20; char* pBuffer = new char[NUMELEMENTS * sizeof(A)]; A* pA = (A*)pBuffer; for (int i = 0; i < NUMELEMENTS; ++i) { pA[i] = new(pA + i) A(); } printf("Buffer address: %x, Array address: %x\n", pBuffer, pA); // Manual destruction for (int i = 0; i < NUMELEMENTS; ++i) { pA[i].~A(); } delete[] pBuffer; return 0; }
This method explicitly controls the placement of each object in the array and ensures that destruction is performed correctly.
Conclusion
Using placement new for arrays requires careful consideration of compiler-specific overhead. The proposed solution offers a portable alternative by allocating and destroying array elements individually.
The above is the detailed content of Is Placement New for Arrays Truly Portable in C ?. For more information, please follow other related articles on the PHP Chinese website!