473,405 Members | 2,261 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Q: address of operator new/delete

Hi,

is it possible to get the address of operator new/delete and operator
new[]/delete[] portably? Otherwise I would have to go for a non-portable and
rather unclean solution.

Thanks for any hints!
--
jb

(replace y with x if you want to reply by e-mail)
Jul 19 '05 #1
21 2697

"Jakob Bieling" <ne*****@gmy.net> wrote in message news:bj*************@news.t-online.com...
Hi,

is it possible to get the address of operator new/delete and operator
new[]/delete[] portably? Otherwise I would have to go for a non-portable and
rather unclean solution.


#include <new>

using namespace std;

int main() {
void* (*ona)(size_t) = &operator new[];
}

Jul 19 '05 #2
On Thu, 4 Sep 2003 17:33:18 +0200, "Jakob Bieling" <ne*****@gmy.net>
wrote:
Hi,

is it possible to get the address of operator new/delete and operator
new[]/delete[] portably? Otherwise I would have to go for a non-portable and
rather unclean solution.


AFAIK, this is fine and portable:

#include <cstddef>
#include <new>

struct A
{
void* operator new(size_t)
{
throw std::bad_alloc();
}
};

int main()
{
void* (*ptr1)(std::size_t) = ::operator new;
void* (*ptr2)(std::size_t) = &A::operator new;
}

Tom
Jul 19 '05 #3
"Ron Natalie" <ro*@sensor.com> wrote in message
news:3f***********************@news.newshosting.co m...

"Jakob Bieling" <ne*****@gmy.net> wrote in message

news:bj*************@news.t-online.com...
Hi,

is it possible to get the address of operator new/delete and operator new[]/delete[] portably? Otherwise I would have to go for a non-portable and rather unclean solution.


#include <new>

using namespace std;

int main() {
void* (*ona)(size_t) = &operator new[];
}

Oh I see. I tried to convert it to a void* directly and I prolly did not
know which overloaded operator's address I wanted. With a static_cast it
works now.

Thanks!
--
jb

(replace y with x if you want to reply by e-mail)
Jul 19 '05 #4

"Jakob Bieling" <ne*****@gmy.net> wrote in message news:bj*************@news.t-online.com...
Oh I see. I tried to convert it to a void* directly and I prolly did not
know which overloaded operator's address I wanted. With a static_cast it
works now.


You can't convert it to void* portably at all. void* is only guaranteed to be
able to hold pointers to (data) objects. You need to use some sort of function
pointer (even if you must cast it) to hold a function pointer.
Jul 19 '05 #5
"Ron Natalie" <ro*@sensor.com> wrote in message
news:3f***********************@news.newshosting.co m...

"Jakob Bieling" <ne*****@gmy.net> wrote in message news:bj*************@news.t-online.com...
Oh I see. I tried to convert it to a void* directly and I prolly did not know which overloaded operator's address I wanted. With a static_cast it
works now.
You can't convert it to void* portably at all. void* is only guaranteed

to be able to hold pointers to (data) objects. You need to use some sort of function pointer (even if you must cast it) to hold a function pointer.

Well, I was not going to cast it back for use. I just wanted to store
the address to be able to print it out and void* seemed somewhat
appropriate. What else would you suggest?

regards
--
jb

(replace y with x if you want to reply by e-mail)
Jul 19 '05 #6

"Jakob Bieling" <ne*****@gmy.net> wrote in message
news:bj*************@news.t-online.com...
I tried to convert it to a void* directly and I prolly did not
know which overloaded operator's address I wanted.

Little typo there btw. I meant to say "[..] and it prolly did not know
which overloaded operator's address I wanted".
--
jb

(replace y with x if you want to reply by e-mail)
Jul 19 '05 #7
On Thu, 4 Sep 2003 18:27:32 +0200, "Jakob Bieling" <ne*****@gmy.net>
wrote:
"Ron Natalie" <ro*@sensor.com> wrote in message
news:3f***********************@news.newshosting.c om...

"Jakob Bieling" <ne*****@gmy.net> wrote in message

news:bj*************@news.t-online.com...
> Oh I see. I tried to convert it to a void* directly and I prolly didnot > know which overloaded operator's address I wanted. With a static_cast it
> works now.


You can't convert it to void* portably at all. void* is only guaranteed

to be
able to hold pointers to (data) objects. You need to use some sort of

function
pointer (even if you must cast it) to hold a function pointer.

Well, I was not going to cast it back for use. I just wanted to store
the address to be able to print it out and void* seemed somewhat
appropriate. What else would you suggest?


It is legal to reinterpret_cast to a sufficiently large integer type -
I'd recommend unsigned long.

Compilers are required to issue a diagnostic if you cast a function
pointer to an object pointer, although there is a defect report
exploring this issue:

http://std.dkuug.dk/jtc1/sc22/wg21/d...ctive.html#195

Tom
Jul 19 '05 #8
tom_usenet wrote:

It is legal to reinterpret_cast to a sufficiently large integer type -
I'd recommend unsigned long.


Do you think that ptr_diff_t is more appropriate than unsigned long ?

Jul 19 '05 #9
Jakob Bieling wrote:
...
is it possible to get the address of operator new/delete and operator
new[]/delete[] portably? Otherwise I would have to go for a non-portable and
rather unclean solution.
...


It is possible, as others already stated. But keep in mind that the
functionality of functions 'operator new/delete' contains only a portion
of functionality of a new/delete expression (for class types with
non-trivial construction and destruction at least). If you want to
create a pointer to something that would reproduce the complete
functionality of new/delete expression, you'll have to write a dedicated
wrapper function (or use a library that provides one).

--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP

Jul 19 '05 #10

"Jakob Bieling" <ne*****@gmy.net> wrote in message news:bj*************@news.t-online.com...

Well, I was not going to cast it back for use. I just wanted to store
the address to be able to print it out and void* seemed somewhat
appropriate. What else would you suggest?


There's no guarantee it will fit. I'd just use the void * (*)() type I
suggested before and cast it to a large integer and hope that's good
enough.
Jul 19 '05 #11

"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:bj********@dispatch.concentric.net...
tom_usenet wrote:

It is legal to reinterpret_cast to a sufficiently large integer type -
I'd recommend unsigned long.


Do you think that ptr_diff_t is more appropriate than unsigned long ?

ptr_diff_t isn't necessarily the right answer. All that has to be is big
enough to hold the difference in offsets in the largest allocatable
array and still that's object sizes not code sizes. size_t is almost
certainly as big or bigger than ptr_diff_t, but it's still no guarantee.

Jul 19 '05 #12
"Andrey Tarasevich" <an**************@hotmail.com> wrote in message
news:vl************@news.supernews.com...
Jakob Bieling wrote:
...
is it possible to get the address of operator new/delete and operator new[]/delete[] portably? Otherwise I would have to go for a non-portable and rather unclean solution.
...


It is possible, as others already stated. But keep in mind that the
functionality of functions 'operator new/delete' contains only a portion
of functionality of a new/delete expression (for class types with
non-trivial construction and destruction at least). If you want to
create a pointer to something that would reproduce the complete
functionality of new/delete expression, you'll have to write a dedicated
wrapper function (or use a library that provides one).

I already replied to Tom's message, that the pointers will not be used
to call the functions. What I meant is, I solely want to be able to uniquely
identify functions, and their addresses are the perfect id. Instead of
having them stored in pointers, I just want the numerical value. Looks like
I will store them in a size_t or unsigned long by using a cast.

Thanks
--
jb

(replace y with x if you want to reply by e-mail)
Jul 19 '05 #13
Ron Natalie wrote:
"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:bj********@dispatch.concentric.net...
tom_usenet wrote:

It is legal to reinterpret_cast to a sufficiently large integer type -
I'd recommend unsigned long.


Do you think that ptr_diff_t is more appropriate than unsigned long ?


ptr_diff_t isn't necessarily the right answer. All that has to be is big
enough to hold the difference in offsets in the largest allocatable
array and still that's object sizes not code sizes. size_t is almost
certainly as big or bigger than ptr_diff_t, but it's still no guarantee.


Where is the definition ?

So this code is undefined ? (a little contrived ...)

int main()
{

char foo[ 1 ];

ptr_diff_t x = foo - ( char * ) 0;

char * foo_ptr = x + ( char * ) 0;

return foo == foo_ptr;
}

Jul 19 '05 #14
to********@hotmail.com (tom_usenet) writes:
On Thu, 4 Sep 2003 18:27:32 +0200, "Jakob Bieling" <ne*****@gmy.net>
wrote:
"Ron Natalie" <ro*@sensor.com> wrote in message
news:3f***********************@news.newshosting. com...

"Jakob Bieling" <ne*****@gmy.net> wrote in message

news:bj*************@news.t-online.com...

> Oh I see. I tried to convert it to a void* directly and I prolly did

not
> know which overloaded operator's address I wanted. With a static_cast it
> works now.

You can't convert it to void* portably at all. void* is only guaranteed

to be
able to hold pointers to (data) objects. You need to use some sort of

function
pointer (even if you must cast it) to hold a function pointer.

Well, I was not going to cast it back for use. I just wanted to store
the address to be able to print it out and void* seemed somewhat
appropriate. What else would you suggest?


It is legal to reinterpret_cast to a sufficiently large integer type -
I'd recommend unsigned long.

[snip]

But why, when storing it in a void(*)() is guaranteed safe? There are
platforms (rather, compiler flag sets on 64bit platforms) on which
code pointers are 64 bit, but unsigned long is only 32.

Jul 19 '05 #15

"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:bj********@dispatch.concentric.net...
So this code is undefined ? (a little contrived ...) char foo[ 1 ];

ptr_diff_t x = foo - ( char * ) 0;
Aboslutely. You can only compare between two pointer values that
point into the same array.

char * foo_ptr = x + ( char * ) 0;

This doesn't even compile. You can't add pointers.
Jul 19 '05 #16

"llewelly" <ll*********@xmission.dot.com> wrote in message news:86************@Zorthluthik.local.bar...
But why, when storing it in a void(*)() is guaranteed safe? There are
platforms (rather, compiler flag sets on 64bit platforms) on which
code pointers are 64 bit, but unsigned long is only 32.


Because void(*)() would have to be a 64-bit type. The standard doesn't
guarantee that there is any integral type that is big enough to hold a function
pointer, but says that if there is one, you can convert back and forth to it
without information loss.
Jul 19 '05 #17
Ron Natalie wrote:
"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:bj********@dispatch.concentric.net...

So this code is undefined ? (a little contrived ...)
char foo[ 1 ];

ptr_diff_t x = foo - ( char * ) 0;

it's ptrdiff_t ...


Aboslutely. You can only compare between two pointer values that
point into the same array.
I have this humungous char array that starts from ( char * ) 0 ...

char * foo_ptr = x + ( char * ) 0;

This doesn't even compile. You can't add pointers.


ptrdiff_t in an integral type - you can add them to pointers as much as
you like.


This compiles for me on GCC 3.3.1 and MSVC 6.0.

#include <cstddef>

int main()
{

char foo[ 1 ];

ptrdiff_t x = foo - ( char * ) 0;

char * foo_ptr = x + ( char * ) 0;

return foo == foo_ptr;
}
It's been a very long time but from what I remember, ptrdiff_t is
supposed to guarentee that it is able to hold a pointer. It becomes
somewhat difficult to write memory allocators it this is not true.

On a machine with 64 bit pointers ptrdiff_t is a 64 bit integer type.

It would make very little sense to be otherwise.

Jul 19 '05 #18

"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:bj********@dispatch.concentric.net...

I have this humungous char array that starts from ( char * ) 0 ...
No you do not. There is no object that has a pointer value (char*) 0 by
definition. This value is distinct from any other

This compiles for me on GCC 3.3.1 and MSVC 6.0.

The compiler is not required to catch this undefined behavior.
It's been a very long time but from what I remember, ptrdiff_t is
supposed to guarentee that it is able to hold a pointer.
Yoiu don't remember (or never understood to begin with). ptrdiff_t
is an implementation defined type. The only time subtraction is
valid is the result of subtracting two pointers into the same
array. Other uses are UNDEFINED BEHAVIOR. Read 5.7, additive
operators.

size_t is an unsigned value big enough to hold the size of any object
(that is it is the type of the return of sizeof).
On a machine with 64 bit pointers ptrdiff_t is a 64 bit integer type.

It would make very little sense to be otherwise.

It still doesn't mean anything with regard to function pointers. There have
been machines where the object pointers are one size and the instruction
pointers are larger.

Jul 19 '05 #19
"Ron Natalie" <ro*@sensor.com> writes:
"llewelly" <ll*********@xmission.dot.com> wrote in message news:86************@Zorthluthik.local.bar...
But why, when storing it in a void(*)() is guaranteed safe? There are
platforms (rather, compiler flag sets on 64bit platforms) on which
code pointers are 64 bit, but unsigned long is only 32.
Because void(*)() would have to be a 64-bit type.


If code pointers are 64 bit, why wouldn't void(*)() be 64-bit?
The standard doesn't guarantee that there is any integral type that
is big enough to hold a function

pointer, but says that if there is one, you can convert back and forth to it
without information loss.


Agreed, but 5.2.10/6 guarantees that reinterpret_cast<> can be used to
covert amoungst pointer to function types without loss, without
the implementation dependency of using an integral type.

Jul 19 '05 #20

"llewelly" <ll*********@xmission.dot.com> wrote in message news:86************@Zorthluthik.local.bar...
"Ron Natalie" <ro*@sensor.com> writes:
"llewelly" <ll*********@xmission.dot.com> wrote in message news:86************@Zorthluthik.local.bar...
But why, when storing it in a void(*)() is guaranteed safe? There are
platforms (rather, compiler flag sets on 64bit platforms) on which
code pointers are 64 bit, but unsigned long is only 32.


Because void(*)() would have to be a 64-bit type.


If code pointers are 64 bit, why wouldn't void(*)() be 64-bit?


They would. But data pointers (i.e., void*) and longs may still be 32.

Jul 19 '05 #21
Jakob Bieling wrote in news:bj*************@news.t-online.com:
Hi,

is it possible to get the address of operator new/delete and
operator
new[]/delete[] portably? Otherwise I would have to go for a
non-portable and rather unclean solution.


A brute force approach:

#include <iostream>
#include <ostream>
#include <cstring>
#include <iomanip>

struct function_key
{
template < typename T >
function_key( T *func )
{
void (*temp)() = reinterpret_cast< void (*)() >( func );
std::memcpy( buf, &temp, sizeof( buf ) );
}

bool operator <( function_key const &rhs ) const
{
return std::memcmp( buf, rhs.buf, sizeof( buf ) ) < 0;
}
// etc ...

friend std::ostream &operator << (
std::ostream &os, function_key const &f
);

private:

unsigned char buf[ sizeof( void (*)() ) ];
};
std::ostream &operator << ( std::ostream &os, function_key const &f )
{
// insert code to save os's state ...
os
<< std::hex
<< std::setprecision(2)
<< std::setfill('0')
<< std::uppercase
;

for ( std::size_t i = sizeof( f.buf ); i; )
{
os << std::setw(2) << unsigned( f.buf[ --i ] );
}

// restore os..
return os;
}

void test( int )
{
}

int main()
{
std::cout
<< function_key(
static_cast< void *(*)(std::size_t) >( operator new )
)
<< std::endl
;

std::cout
<< function_key(
static_cast< void *(*)(std::size_t, void *) >( operator new )
)
<< std::endl
;

std::cout << function_key( test ) << std::endl;
}
Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 19 '05 #22

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

24
by: Marcin Vorbrodt | last post by:
Is there any reason why auto_ptr does not have the cast operator like this: operator void* (); So that one could easily test auto_ptr for NULL ??? Standard does not declare such operator. Is...
2
by: skscpp | last post by:
I have a question about multiple inheritance, operator new/delete and ambiguity. Here is some code that I wrote to analyze this problem. // test.h ========================== #include <new>...
1
by: Senthilvel Samatharman | last post by:
I am just curious about the case 3 in the follwouing program. I understand that case 1 is the right way to overload, while Case 2 is erroneous. But i do think that the implementation of operator...
20
by: Ioannis Vranos | last post by:
When we use the standard placement new operator provided in <new>, and not a definition of owr own, isn't a call to placement delete enough? Consider the code: #include <new>
11
by: Jonan | last post by:
Hello, For several reasons I want to replace the built-in memory management with some custom built. The mem management itlsef is not subject to my question - it's ok to the point that I have...
13
by: Amy | last post by:
Hello, We are developing C++ appplications for PDAs where memory is limited, so we want to do memory management by ourselves --- pre-allocated a big chunk and overwrite new and delete to call...
4
by: toton | last post by:
Hi, How to find address of a class from inside? My class having a overloaded new & delete. new allocates the memory like void* operator new(std::size_t size) throw(){ cout<<"op new...
6
by: Lighter | last post by:
Big Problem! How to overload operator delete? According to C++ standard, "A deallocation function can have more than one parameter."(see 3.7.3.2); however, I don't know how to use an overloaded...
10
by: JeanDean | last post by:
MyClass *obj = new MyClass; Even though address returned by new is 0x00365f50, but obj gets automatically updated by 0x00365f54. Why and who adds these addtional 4 bytes to the address?
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.