Simulate new [] with argument constructor

If I do not change any variable staticinside the argument constructor, is it below the appropriate modeling method new T[N] (x,y);(array with arguments)?

template<typename T>
void* operator new [] (size_t size, const T &value)
{
  T* p = (T*) malloc(size);
  for(int i = size / sizeof(T) - 1; i >= 0; i--)
    memcpy(p + i, &value, sizeof(T));
  return p;
}

Use will be

struct A
{
  A () {}  // default
  A (int i, int j) {} // with arguments
};

int main ()
{
  A *p = new(A(1,2)) A[10];  // instead of new A[10](1,2)
}
+5
source share
5 answers

It is not normal. You copy objects to uninitialized memory without causing the correct copy semantics.

While you work only with POD, everything is in order. However, when working with objects that are not PODs (like yours A), you need to take precautions.

, operator new . Alexandre , , ++ operator new, :

#include <cstdlib>
#include <iostream>

template<typename T>
void* operator new [] (size_t size, T value) {
    T* p = (T*) std::malloc(size);
    for(int i = size / sizeof(T) - 1; i >= 0; i--)
        new(p + i) T(value);
    return p;
}

struct A {
    int x;
    A(int x) : x(x) { std::cout << "int ctor\n"; }
    A() : x(0) { std::cout << "default ctor\n"; }
    A(const A& other) : x(other.x) { std::cout << "copy ctor\n"; }
};

int main() {
    A *p = new(A(42)) A[2];
    for (unsigned i = 0; i < 2; ++i)
        std::cout << p[i].x << std::endl;
}

:

int ctor
copy ctor
copy ctor
default ctor
default ctor
0
0

... .

+4

 std::vector<A> v(10, A(1,2));

, .

 p = &v[0]; 

. , p

boost:: array < > ( C), ...

+5

- ++ , typename T (struct A ), .

std::vector () ::operator new[] , , - , .

+2

, operator new[] , sizeof(T) * n.

, , , ++ , delete[] p;, , new p[sz], , (, ), , .

It also means that your attempt to provide already initialized objects will fail, because in fact the array returned to the application will not potentially run at the address that you returned from the user operator new[]so that initialization can be biased.

+1
source
template <typename myType> myType * buildArray(size_t numElements,const myType & startValue) {
  myType * newArray=(myType *)malloc(sizeof(myType)*numElements);

  if (NULL!=newArray) {
    size_t index;
    for (index=0;index<numElements;++index) {
      new (newArray+index) myType(startValue);
    }
  }

  return newArray;
}

template <typename myType> void destroyArray(size_t numElements,myType * oldArray) {
  size_t index;
  for (index=0;index<numElements;++index) {
    (oldArray+index)->~myType();
  }
  free(oldArray);
}

A * p=newArray(10,A(1,2));
destroyArray(10,p);

destroyArray can also be written like this, depending on the platform for which you are building:

template <typename myType> void destroyArray(myType * oldArray) {
  size_t numElements=malloc_size(oldArray)/sizeof(myType); //or _msize with Visual Studio
  size_t index;
  for (index=0;index<numElements;++index) {
    (oldArray+index)->~myType();
  }
  free(oldArray);
}
0
source

All Articles