keyword "new"

Hi I am trying to understand the implementation behind keyword new.

what I have is a simple class (RandomClass.cpp) :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  

void * RandomClass::operator new(size_t size)
{

	
	while(1) // always try to allocate repeatedly
	{
		
		void *mem  = ::operator new(size);



		if(mem)
		{
		std::cout << "Allocation succesfull" << endl;
		return mem;
		}
	
	}


}


when I create an object in main, it will estimate a size of 1 byte and allocate memory. But when I include a string in the header the size is 32 bytes which is already confusing.

RandomClass.h

1
2
3
4
5
6
7
8
9
10
11
12
class RandomClass
{
public:

	std::string name;

	void * operator new(size_t size);
	
	void SayHI();
};



to top it off in my main function I do not understand why the new operator does not return the void * ( is there some implicit cast)

1
2
3
4
5
6
7
8
9
10

int main()
{
	RandomClass *rndmCls = new RandomClass(); // this will allocate n bytes and return RandomClass *
	 
	void * a =  RandomClass::operator new(33); // this will allocate 33 bytes and return void *

	system("pause");

}


I am curious about the implementation of the new keyword, if anyone can point to some links will be most appreciated.
There should be documentation on this site under tutorials and reference; however, my lame approach to a definition is new is responsible for allocating memory. When used to create a class, new calls the class's constructor among other things, returning the proper type of object.

Try this link:

http://www.cplusplus.com/doc/tutorial/dynamic/
Last edited on
You need to distinguish between operator new and new-expression.

In code int* i = new int; new refers to the new-expression. new-expression will dtermine size of class, and calls operator new to allocate sufficien amount of memory constructs object in returned memory and then returns pointer of proper type to constructed object.

Without any members you will need to allocate at least 1 byte, as size of object cannot be less than one byte. If you include members, you obviously will need space for them.

http://en.cppreference.com/w/cpp/language/new
http://en.cppreference.com/w/cpp/memory/new/operator_new
What is the point of the loop in RandomClass::operator new? If the allocation fails, trying it again is not going to work. Your program will just go into an infinite loop. The only way a subsequent allocation attempt will succeed is if your program has multiple threads and another thread releases sufficient memory. The usual action here is to return nullptr (ala malloc), or throw an exception.

when I include a string in the header the size is 32 bytes which is already confusing.

That's because std::string is a complex data type and 32 bytes is the size of the class in your implementation. std::string uses heap memory outside the base instance to store strings.

I do not understand why the new operator does not return the void *

I don't understand the question.

In terms of how operator new works, you can think of it very generally as a wrapper for malloc, with the additional feature of calling the object's constructor. Note that implementations are not required to use malloc to allocate heap memory and may use their own heap management.
Last edited on
What is the point of the loop in RandomClass::operator new?


It is from a book by Scott Meyers in chapter memory management, the loop does have a termination but I just did not include it as it did not have anything to do with the question.

I do not understand why the new operator does not return the void *


I asked that because I wanted to know if there is some implicit casting going on which converts pointer to void to some object pointer but I was not aware about the new expression and operator new being different things. Neither did I think string would take so much space so assumed I was doing something wrong but it`s clearer now thanks alot!
It is from a book by Scott Meyers in chapter memory management

Without seeing the actual text of the book, I have to say creating a loop of any kind on an allocation failure is a very bad idea (except possibly in a multi-threaded environment). The loop is going to simply tie up CPU cycles without accomplishing anything. If you're out of memory, you're out of memory. There is no recovery for that. It's a non-recoverable error.

Bottom line (afaik), You're making a new instance of that object rather than refer to the base object itself. Sorry, I'm a newbie myself atm. Well, relatively speaking.
Last edited on
Re: executing a loop in an allocation function

IS:

void* operator new(std::size_t size) ;
...
Default behavior:

— Executes a loop: Within the loop, the function first attempts to allocate the requested storage.
Whether the attempt involves a call to the Standard C library function malloc is unspecified.

— Returns a pointer to the allocated storage if the attempt is successful. Otherwise, if the current new_handler is a null pointer value, throws bad_alloc.

— Otherwise, the function calls the current new_handler function. If the called function returns, the loop repeats.

— The loop terminates when an attempt to allocate the requested storage is successful or when a called new_handler function does not return.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstdlib>
#include <new>

void* operator new( std::size_t sz )
{
    void* pv = nullptr ;

    while( pv == nullptr )
    {
        pv = std::malloc(sz) ;

        if( pv == nullptr )
        {
            const auto new_handler = std::get_new_handler() ;
            if( new_handler == nullptr ) throw std::bad_alloc() ;
            else new_handler() ;
        }
    }

    return pv ;
}
@JLBorges
Thank you, that was very usefull, @AbstractionAnon hope that example explains why you might need the loop.

There is an important difference between what you posted and what JLBorges posted.

In JLBorges' code, if no new_handler is present, an exception is thrown. That is an immediate exit from the loop.

If new_handler is present, it has the opportunity to do some cleanup, return and attempt the malloc again.

That is not the loop that you posted. What you posted was an infinite loop with no opportunity to cleanup the heap.
Topic archived. No new replies allowed.