Reputation: 777
While reading Bruce Eckel i came across the following example:
#include <cstdio>
#include <cstdlib>
using namespace std;
void* operator new(size_t sz)
{
printf("operator new: %d Bytes\n", sz);
void* m = malloc(sz);
if(!m) puts("out of memory");
return m;
}
void operator delete(void* m)
{
puts("operator delete");
free(m);
}
class S {
int i[100];
public:
S() { puts("S::S()"); }
~S() { puts("S::~S()"); }
};
int main() {
puts("creating & destroying an int");
int* p = new int(47);
delete p;
puts("creating & destroying an s");
S* s = new S;
delete s;
puts("creating & destroying S[3]");
S* sa = new S[3];
delete []sa;
}
I am having doubt with following statement:
Notice that printf( )
and puts( )
are used rather than iostreams. This is because when an iostream
object is created (like the global cin
, cout
, and cerr
), it calls operator new
to allocate memory. With printf( )
, you don't get into a deadlock because it doesn't call new
to initialize itself.
However, when i am running the program after replacing put with cout
i am getting no such deadlock. Can anyone explain that?
operator new
returns a void pointer, but finally we are getting pointer to a dynamically allocated object. So is it a constructor that returns a pointer to the object (this, though the constructor doesn't have a return type) or its the compiler that does i internally?
Upvotes: 2
Views: 560
Reputation: 10658
1) The C++ standard contains a lot of "mays" which are not usually used. This is one of them. The operator<< function may use dynamic memory, but it does not have to. Often this is not the case.
So that your example works does not mean it is correct. It just means it works with the implementation you are using. On other implementations it could break.
The "mays" defined by the standard can also go in another direction. For example any STL-Header may include any other standard header, but is not required to do so. This is often the case with the iostream header and the istream and ostream headers. Almost any implementation includes ostream and istream when iostream is used, but technically they don't have to. This means when you use ostream and just include iostream you program might work, but actually it is not correct as far as the standard is concerned.
For both c and c++ it is rather important to know what may silently break, but this is often not very easy.
Upvotes: 2
Reputation: 170489
Use of printf()
to avoid a recursive call into operator new()
is a safety measure - just to be sure it works. How do you know use of iostream
never ever causes a call to operator new()
function?
You're confusing new expression (a language construct) with operator new()
function. new expression indeed returns a typed pointer, but the a call to operator new()
function is done "under the hood" and operator new()
function returns void*
. The compiler generates all necessary code for that.
Upvotes: 1