stefarg
asked on
Problem using STL due to definition of operator new(unsigned int,void *)
Hey All,
I am working with the Darwin Streaming Server and I am trying to implement some of my own classes that need to use the STL queue libraries but there is an error occuring when use #include <queue>, as follows:
/CommonUtilitiesLib/OSMemo ry.h(125) : error C2084: function 'void *__cdecl operator new(unsigned int,void *)' already has a body
I have looked at this function and it is as follows:
// PLACEMENT NEW OPERATOR
inline void* operator new(size_t, void* ptr) { return ptr;}
and I assume that somewhere in the STL this function is also declared + defined.
So here's the problem, I want be able to use the STL libraries and not cause damage to the rest of the darwin code. I tried just commenting out the function in darwin, in the hope that the implementation in the STL would be picked up but it wasn't. (I'm fairly confident, though not certain, that the STL function and the one in darwin are identical).
Is there some #ifndef/#define type condition I could put around the funtion in the OSMemory.h file to prevent the problem or if anyone has a neat solution to this problem please reply.
This is fairly urgent,
Thanks,
Stef
I am working with the Darwin Streaming Server and I am trying to implement some of my own classes that need to use the STL queue libraries but there is an error occuring when use #include <queue>, as follows:
/CommonUtilitiesLib/OSMemo
I have looked at this function and it is as follows:
// PLACEMENT NEW OPERATOR
inline void* operator new(size_t, void* ptr) { return ptr;}
and I assume that somewhere in the STL this function is also declared + defined.
So here's the problem, I want be able to use the STL libraries and not cause damage to the rest of the darwin code. I tried just commenting out the function in darwin, in the hope that the implementation in the STL would be picked up but it wasn't. (I'm fairly confident, though not certain, that the STL function and the one in darwin are identical).
Is there some #ifndef/#define type condition I could put around the funtion in the OSMemory.h file to prevent the problem or if anyone has a neat solution to this problem please reply.
This is fairly urgent,
Thanks,
Stef
You may have better luck posting this in the "Macintosh Programming" area (or you may not... it's awfully quiet over there). THe best thing to do would be to post a "pointer question" in the "Mac Programming" area (e.g. a 20 point question that points to this question). Have the pointer question deleted and your points refunded once this question here is answered.
Actually, this goes this way
If u overload the operator new globally (as u have done above), then that would be used whenever memory is allocated using new operator
If u wish to have some special kind of allocation for some specific class, u could overload the new operator for the class
Thus, only objects of that class allocated thru new would use yoru version, else the default new would be used
Amit
If u overload the operator new globally (as u have done above), then that would be used whenever memory is allocated using new operator
If u wish to have some special kind of allocation for some specific class, u could overload the new operator for the class
Thus, only objects of that class allocated thru new would use yoru version, else the default new would be used
Amit
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hey Sys Prog,
Unfortunately making it a member method does not work, it just gives an error complaining the constructor did not expect 2 parameters,
Thanks for the suggestion though,
Stef
Unfortunately making it a member method does not work, it just gives an error complaining the constructor did not expect 2 parameters,
Thanks for the suggestion though,
Stef
ASKER
Hey jkr,
No luck there either, just gave the errors:
c:\program files\microsoft visual studio\vc98\include\xstrin g(525) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
c:\program files\microsoft visual studio\vc98\include\xstrin g(521) : while compiling class-template member function 'void __thiscall std::basic_string<char,str uct std::char_traits<char>,cla ss std::allocator<char> >::_Copy(unsigned int)'
c:\program files\microsoft visual studio\vc98\include\xmemor y(34) : error C2665: 'new' : none of the 2 overloads can convert parameter 2 from type 'void *'
c:\program files\microsoft visual studio\vc98\include\xmemor y(66) : see reference to function template instantiation 'void __cdecl std::_Construct(unsigned int *,const unsigned int &)' being compiled
QTRTPFile.cpp
c:\program files\microsoft visual studio\vc98\include\xstrin g(525) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
c:\program files\microsoft visual studio\vc98\include\xstrin g(521) : while compiling class-template member function 'void __thiscall std::basic_string<char,str uct std::char_traits<char>,cla ss std::allocator<char> >::_Copy(unsigned int)'
c:\program files\microsoft visual studio\vc98\include\xmemor y(34) : error C2665: 'new' : none of the 3 overloads can convert parameter 2 from type 'void *'
c:\program files\microsoft visual studio\vc98\include\xmemor y(66) : see reference to function template instantiation 'void __cdecl std::_Construct(unsigned int *,const unsigned int &)' being compiled
Once again, thanks for you suggestion!
No luck there either, just gave the errors:
c:\program files\microsoft visual studio\vc98\include\xstrin
c:\program files\microsoft visual studio\vc98\include\xstrin
c:\program files\microsoft visual studio\vc98\include\xmemor
c:\program files\microsoft visual studio\vc98\include\xmemor
QTRTPFile.cpp
c:\program files\microsoft visual studio\vc98\include\xstrin
c:\program files\microsoft visual studio\vc98\include\xstrin
c:\program files\microsoft visual studio\vc98\include\xmemor
c:\program files\microsoft visual studio\vc98\include\xmemor
Once again, thanks for you suggestion!
ASKER
The only place that I can see in the code where the 'new' operator defined by darwin is used is:
char* theNewBuf = NEW char[fBufSize + sizeof(OSQueueElem)];
....
(void)new (theNewBuf) OSQueueElem(theNewBuf + sizeof(OSQueueElem));
I am quite confused regarding the syntax used here!! what are the two parameters passed here?
why is there (void) at the start, is this the void the first parameter? Therefore would this operator overloading have a similar syntax to overload an == or < etc?
Maybe I could add an extra parameter to distinguish the 2 funtions and then just pass NULL as one of the arguements in the line above? If this is the case, how would I alter the new function to take 3 parameters? Is it even possible?
My last resort would be write my own queue and priority_queue classes, however I need this fairly urgently and don't really hae time to be writing them. So if someone can post up code for an EFFICIENT queue and priority queue that doesn't use the STL (i.e. using just arrays) I will award the points to them.
char* theNewBuf = NEW char[fBufSize + sizeof(OSQueueElem)];
....
(void)new (theNewBuf) OSQueueElem(theNewBuf + sizeof(OSQueueElem));
I am quite confused regarding the syntax used here!! what are the two parameters passed here?
why is there (void) at the start, is this the void the first parameter? Therefore would this operator overloading have a similar syntax to overload an == or < etc?
Maybe I could add an extra parameter to distinguish the 2 funtions and then just pass NULL as one of the arguements in the line above? If this is the case, how would I alter the new function to take 3 parameters? Is it even possible?
My last resort would be write my own queue and priority_queue classes, however I need this fairly urgently and don't really hae time to be writing them. So if someone can post up code for an EFFICIENT queue and priority queue that doesn't use the STL (i.e. using just arrays) I will award the points to them.
I'm don't know what Darwin Streaming Server is, but ...
Wrap it's inclusion in a custom namespace. This would bring it's globally scoped items into that namespace. Hence no conflicts.
namespace Darwin
{
#include "Darwin.h" // ... whatever
}
Wrap it's inclusion in a custom namespace. This would bring it's globally scoped items into that namespace. Hence no conflicts.
namespace Darwin
{
#include "Darwin.h" // ... whatever
}
>>stefarg
Can you post more of the code declaration, so that we can get a more complete picture.
Post the header that contians the new operator
Can you post more of the code declaration, so that we can get a more complete picture.
Post the header that contians the new operator
ASKER
Hey there Axter,
Here's the header file:
-------------------------- --------OS Memory.h-- ---------- ---------- ---------- ---------- ---------- ---
#ifndef __OS_MEMORY_H__
#define __OS_MEMORY_H__
#include "OSHeaders.h"
#include "OSQueue.h"
#include "OSMutex.h"
class OSMemory
{
public:
#if MEMORY_DEBUGGING
//If memory debugging is on, clients can get access to data structures that give
//memory status.
static OSQueue* GetTagQueue() { return &sTagQueue; }
static OSMutex* GetTagQueueMutex() { return &sMutex; }
static UInt32 GetAllocatedMemory() { return sAllocatedBytes; }
static void* DebugNew(size_t size, char* inFile, int inLine, Bool16 sizeCheck);
static void DebugDelete(void *mem);
static Bool16 MemoryDebuggingTest();
static void ValidateMemoryQueue();
enum
{
kMaxFileNameSize = 48
};
struct TagElem
{
OSQueueElem elem;
char fileName[kMaxFileNameSize] ;
int line;
UInt32 tagSize; //how big are objects of this type?
UInt32 totMemory; //how much do they currently occupy
UInt32 numObjects;//how many are there currently?
};
#endif
// Provides non-debugging behaviour for new and delete
static void* New(size_t inSize);
static void Delete(void* inMemory);
//When memory allocation fails, the server just exits. This sets the code
//the server exits with
static void SetMemoryError(SInt32 inErr);
#if MEMORY_DEBUGGING
private:
struct MemoryDebugging
{
OSQueueElem elem;
TagElem* tagElem;
UInt32 size;
};
static OSQueue sMemoryQueue;
static OSQueue sTagQueue;
static UInt32 sAllocatedBytes;
static OSMutex sMutex;
#endif
};
// NEW MACRO
// When memory debugging is on, this macro transparently uses the memory debugging
// overridden version of the new operator. When memory debugging is off, it just compiles
// down to the standard new.
#if MEMORY_DEBUGGING
#ifdef NEW
#error Conflicting Macro "NEW"
#endif
#define NEW new (__FILE__, __LINE__)
#else
#ifdef NEW
#error Conflicting Macro "NEW"
#endif
#define NEW new
#endif
/************************* ********** ********** ********** ****/
//HERE IS THE NEW DECLARATION OF THE OPERATOR THAT IS CAUSING ME THE
//TROUBLE.
// PLACEMENT NEW OPERATOR
inline void* operator new(size_t, char* ptr) { return ptr;}
/************************* ********** ********** ********** ****/
#if MEMORY_DEBUGGING
// These versions of the new operator with extra arguments provide memory debugging
// features.
void* operator new(size_t s, char* inFile, int inLine);
void* operator new[](size_t s, char* inFile, int inLine);
#endif
// When memory debugging is not on, these are overridden so that if new fails,
// the process will exit.
void* operator new (size_t s);
void* operator new[](size_t s);
void operator delete(void* mem);
void operator delete[](void* mem);
#endif //__OS_MEMORY_H__
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- --
And here is the cpp file that uses the new declaration:
-------------------------- ---------O SBufferPoo l.cpp----- ---------- ---------- ---------- --------
#include "OSBufferPool.h"
#include "OSMemory.h"
void* OSBufferPool::Get()
{
OSMutexLocker locker(&fMutex);
if (fQueue.GetLength() == 0)
{
fTotNumBuffers++;
char* theNewBuf = NEW char[fBufSize + sizeof(OSQueueElem)];
//
// We need to construct a Queue Element, but we don't actually need
// to use it in this function, so to avoid a compiler warning just
// don't assign the result to anything.
(void)new (theNewBuf) OSQueueElem(theNewBuf + sizeof(OSQueueElem));
return theNewBuf + sizeof(OSQueueElem);
}
return fQueue.DeQueue()->GetEnclo singObject ();
}
void OSBufferPool::Put(void* inBuffer)
{
OSMutexLocker locker(&fMutex);
fQueue.EnQueue((OSQueueEle m*)((char* )inBuffer - sizeof(OSQueueElem)));
}
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- --
Here's the header file:
--------------------------
#ifndef __OS_MEMORY_H__
#define __OS_MEMORY_H__
#include "OSHeaders.h"
#include "OSQueue.h"
#include "OSMutex.h"
class OSMemory
{
public:
#if MEMORY_DEBUGGING
//If memory debugging is on, clients can get access to data structures that give
//memory status.
static OSQueue* GetTagQueue() { return &sTagQueue; }
static OSMutex* GetTagQueueMutex() { return &sMutex; }
static UInt32 GetAllocatedMemory() { return sAllocatedBytes; }
static void* DebugNew(size_t size, char* inFile, int inLine, Bool16 sizeCheck);
static void DebugDelete(void *mem);
static Bool16 MemoryDebuggingTest();
static void ValidateMemoryQueue();
enum
{
kMaxFileNameSize = 48
};
struct TagElem
{
OSQueueElem elem;
char fileName[kMaxFileNameSize]
int line;
UInt32 tagSize; //how big are objects of this type?
UInt32 totMemory; //how much do they currently occupy
UInt32 numObjects;//how many are there currently?
};
#endif
// Provides non-debugging behaviour for new and delete
static void* New(size_t inSize);
static void Delete(void* inMemory);
//When memory allocation fails, the server just exits. This sets the code
//the server exits with
static void SetMemoryError(SInt32 inErr);
#if MEMORY_DEBUGGING
private:
struct MemoryDebugging
{
OSQueueElem elem;
TagElem* tagElem;
UInt32 size;
};
static OSQueue sMemoryQueue;
static OSQueue sTagQueue;
static UInt32 sAllocatedBytes;
static OSMutex sMutex;
#endif
};
// NEW MACRO
// When memory debugging is on, this macro transparently uses the memory debugging
// overridden version of the new operator. When memory debugging is off, it just compiles
// down to the standard new.
#if MEMORY_DEBUGGING
#ifdef NEW
#error Conflicting Macro "NEW"
#endif
#define NEW new (__FILE__, __LINE__)
#else
#ifdef NEW
#error Conflicting Macro "NEW"
#endif
#define NEW new
#endif
/*************************
//HERE IS THE NEW DECLARATION OF THE OPERATOR THAT IS CAUSING ME THE
//TROUBLE.
// PLACEMENT NEW OPERATOR
inline void* operator new(size_t, char* ptr) { return ptr;}
/*************************
#if MEMORY_DEBUGGING
// These versions of the new operator with extra arguments provide memory debugging
// features.
void* operator new(size_t s, char* inFile, int inLine);
void* operator new[](size_t s, char* inFile, int inLine);
#endif
// When memory debugging is not on, these are overridden so that if new fails,
// the process will exit.
void* operator new (size_t s);
void* operator new[](size_t s);
void operator delete(void* mem);
void operator delete[](void* mem);
#endif //__OS_MEMORY_H__
--------------------------
And here is the cpp file that uses the new declaration:
--------------------------
#include "OSBufferPool.h"
#include "OSMemory.h"
void* OSBufferPool::Get()
{
OSMutexLocker locker(&fMutex);
if (fQueue.GetLength() == 0)
{
fTotNumBuffers++;
char* theNewBuf = NEW char[fBufSize + sizeof(OSQueueElem)];
//
// We need to construct a Queue Element, but we don't actually need
// to use it in this function, so to avoid a compiler warning just
// don't assign the result to anything.
(void)new (theNewBuf) OSQueueElem(theNewBuf + sizeof(OSQueueElem));
return theNewBuf + sizeof(OSQueueElem);
}
return fQueue.DeQueue()->GetEnclo
}
void OSBufferPool::Put(void* inBuffer)
{
OSMutexLocker locker(&fMutex);
fQueue.EnQueue((OSQueueEle
}
--------------------------
ASKER
ok, based on jkr's suggestion I came up with a variation where I put #define around the function as follows:
#ifndef __PLACEMENT_NEW_INLINE
#define __PLACEMENT_NEW_INLINE
inline void* operator new(size_t, void* ptr) { return ptr;}
#endif __PLACEMENT_NEW_INLINE
and it removed the problem, (although just using it at the include did not work).
However then there was a warning appearing about exceptions:
"C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX."
But I found a solution to this at http://support.microsoft.com/default.aspx?scid=kb;en-us;q154419
So thanks for your help everyone, I think I can lay this one to rest now.
I am very grateful for all comments and suggestions,
Many thanks,
Stef
#ifndef __PLACEMENT_NEW_INLINE
#define __PLACEMENT_NEW_INLINE
inline void* operator new(size_t, void* ptr) { return ptr;}
#endif __PLACEMENT_NEW_INLINE
and it removed the problem, (although just using it at the include did not work).
However then there was a warning appearing about exceptions:
"C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX."
But I found a solution to this at http://support.microsoft.com/default.aspx?scid=kb;en-us;q154419
So thanks for your help everyone, I think I can lay this one to rest now.
I am very grateful for all comments and suggestions,
Many thanks,
Stef