Home > Backend Development > C++ > Is Placement New for Arrays Truly Portable in C ?

Is Placement New for Arrays Truly Portable in C ?

Mary-Kate Olsen
Release: 2024-11-15 04:05:02
Original
627 people have browsed it

Is Placement New for Arrays Truly Portable in C  ?

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;
}
Copy after login

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;
}
Copy after login

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!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template