Where is the `size` coming from?
Asked Answered
F

3

7

I know there should be a delete operator with which I'm not concerned in somewhere. I just wondering, wow, it worked. Where is the argument "size" coming from?

#include<iostream>
#include<string>

class Base {
public:
    Base() { }
    void *operator new( unsigned int size, std::string str ) {
    std::cout << "Logging an allocation of ";
    std::cout << size;
    std::cout << " bytes for new object '";
    std::cout << str;
    std::cout << "'";
    std::cout << std::endl;
    return malloc( size );
    }
private:
    int var1;
    double var2;
};

int main(int argc, char** argv){
    Base* b = new ("Base instance 1") Base;
}

Here is the result:

Logging an allocation of 16 bytes for new object 'Base instance 1'

Farant answered 24/8, 2011 at 11:7 Comment(10)
You are looking at some fairly advanced C++ features. As a beginner you should maybe focus on more basic stuff.Bastille
Beware, size of an object and the allocated number of bytes might be different due to alignment, padding and other overheads! Especially true for arrays. Don't assume the object is placed at the address you returned in your operator new, cause it might not be!Lucic
Actually from the standard 5.3.4/12: "new T results in a call of operator new(sizeof(T))". If you want any special alignment you'll have to provide it yourself and the object will be placed at the address returned from new.William
I'm not sure about objects, but for arrays, there is definitely some overhead. That is why my custom lengthof function failed - the allocated size isn't a multiple of the size of the type, and the address of the array and the allocated memory differ.Lucic
@Lucic Can you post an example, either as a question here on SO or somewhere else (codepad.org etc)?William
@Lucic Ok, saw your question. As you probably noted overhead is only allowed for arrays.William
@Andreas Brinck: Not sure how 5.3.4/12 applies as this is placement new.Marcos
@Frigo: Don't make assumptions about how the standard works. There is no requirement for extra space thus it may not use (in any way thay you are thinking about). How the size of the array is determined is deliberately left as an implementation detail to allow the compiler to be more efficient on platforms that it can be.Marcos
@Martin As far as I can tell this is not placement new, but calling a class specific allocation function with extra parameters, as described in 12.5 in the standard. Am I mistaken?William
@Martin Or is this still referred to as placement new, i.e. invoking B's constructor in the memory returned from B::operator new? Why wouldn't 5.3.4/12 still apply though?William
W
14

It is provided by the compiler at compile time. When the compiler sees:

new ("Base instance 1") Base;

it will add a call to:

Base::operator new(sizeof(Base), "Base instance 1");

EDIT: The compiler will of course also add a call to Base::Base()

William answered 24/8, 2011 at 11:10 Comment(1)
You are awesome.Thank you! Amazing.I changed the code and got an error:first formal parameter to 'operator new' must be 'size_t'.Now I know a little more about new.Thanks again.Farant
C
0

on 32 bit arch int is 4 bytes, double is 8, but the double is going to be aligned to 8 byte boundary so size = 4 + 4(empty space) + 8 = 16

Charnel answered 24/8, 2011 at 11:13 Comment(1)
the question was not how the size of the type came to existence, but about the size parameter to new, and where it will be filled fromDorotea
G
0

"placement operator new" is called , thats why size 16 bytes from the

std::cout << sizeof("Base instance 1");

void* operator new(size_t sz,void* ptr) noexcept;
Gussy answered 30/8 at 14:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.