Array placement-new requires unspecified overhead in the buffer?

前端 未结 6 1185
甜味超标
甜味超标 2020-11-22 15:09

5.3.4 [expr.new] of the C++11 Feb draft gives the example:

new(2,f) T[5] results in a call of operator new[](sizeof(T)*5+

6条回答
  •  南笙
    南笙 (楼主)
    2020-11-22 16:03

    Update: After some discussion, I understand that my answer no longer applies to the question. I'll leave it here, but a real answer is definitely still called for.

    I'll be happy to support this question with some bounty if a good answer isn't found soon.

    I'll restate the question here as far as I understand it, hoping that a shorter version might help others understand what's being asked. The question is:

    Is the following construction always correct? Is arr == addr at the end?

    void * addr = std::malloc(N * sizeof(T));
    T * arr = ::new (addr) T[N];                // #1
    

    We know from the standard that #1 causes the call ::operator new[](???, addr), where ??? is an unspecified number no smaller than N * sizeof(T), and we also know that that call only returns addr and has no other effects. We also know that arr is offset from addr correspondingly. What we do not know is whether the memory pointed to by addr is sufficiently large, or how we would know how much memory to allocate.


    You seem to confuse a few things:

    1. Your example calls operator new[](), not operator new().

    2. The allocation functions do not construct anything. They allocate.

    What happens is that the expression T * p = new T[10]; causes:

    1. a call to operator new[]() with size argument 10 * sizeof(T) + x,

    2. ten calls to the default constructor of T, effectively ::new (p + i) T().

    The only peculiarity is that the array-new expression asks for more memory than what is used by the array data itself. You don't see any of this and cannot make use of this information in any way other than by silent acceptance.


    If you are curious how much memory was actually allocated, you can simply replace the array allocation functions operator new[] and operator delete[] and make it print out the actual size.


    Update: As a random piece of information, you should note that the global placement-new functions are required to be no-ops. That is, when you construct an object or array in-place like so:

    T * p = ::new (buf1) T;
    T * arr = ::new (buf10) T[10];
    

    Then the corresponding calls to ::operator new(std::size_t, void*) and ::operator new[](std::size_t, void*) do nothing but return their second argument. However, you do not know what buf10 is supposed to point to: It needs to point to 10 * sizeof(T) + y bytes of memory, but you cannot know y.

提交回复
热议问题