模块间调用重载new和delete问题

模块间调用重载new和delete问题

模块间调用重载new和delete问题:
1.问题:
 在我们的客户端运行代码中new了一个静态库中的一个类,然后立即delete它,
发现在delete时出错!如下代码:
kServer *pSvr = new kServer;
delete pSvr;
2.原因:
     跟踪发现在new时进入了重载的全局operator new(我们的客户端引入了重载
   new和delete操作符的文件头), 而在delete时没有(调用的却是原来的delete).
3.为什么会这样:
 不是很清楚,可能是编译器的问题.
4.解决方案:
  [方法一]:
      找到库的实现代码,加入重载new和delete操作符的头文件,问题解决! 
   [方法二]:
   找到库的实现代码,把对应类的构造函数写到头文件中,问题解决!
   [方法三]:
   如果没有库的实现代码(就是说只有库和头文件的话),在客户端new和
   delete时前面各加一个::指示符表明调用的是全局操作符,问题解决!
5.其它:
      另外作了一下测试,发现如果把库换成dll来实现则不会有这个问题,new和
   delete都会调用全局重载的操作符.
6.附(问题的测试代码):
一.动态库(dll)工程文件:
//////////////////////////////////////////////////////////////////////
// Svr1.h: interface for the Svr1 class.
//
//////////////////////////////////////////////////////////////////////
#ifndef __SVR1_H
#define __SVR1_H
// 注:先用vc向导产生动态库工程,并在工程选项中定义宏: DLL_EXPORTS,
//     再加入Svr1.h和Svr1.cpp文件.
#ifdef  DLL_EXPORTS
#define KSVR_API __declspec(dllexport)
#else
#define KSVR_API __declspec(dllimport)
#endif
class KSVR_API Svr1 
{
public:
 Svr1();
 virtual ~Svr1();
};
#endif // __SVR1_H
//////////////////////////////////////////////////////////////////////
// Svr1.cpp: implementation of the Svr1 class.
//
//////////////////////////////////////////////////////////////////////
#include "Svr1.h"
Svr1::Svr1(){}
Svr1::~Svr1(){}
二.静态库工程文件:
//////////////////////////////////////////////////////////////////////
// Svr2.h: interface for the Svr2 class.
//
//////////////////////////////////////////////////////////////////////
#ifndef __SVR2_H
#define __SVR2_H
// 注:先用vc向导产生静态库工程,再加入Svr2.h和Svr2.cpp文件.
#define __INCPP // 定义此行后new出和delete此类对象时调用不配对(new是重载后,delete不是)
class Svr2 
{
public:
#ifdef __INCPP
 Svr2();
#else
 Svr2(){}
#endif
 virtual ~Svr2();
 void test();
};
#endif // __SVR2_H
//////////////////////////////////////////////////////////////////////
// Svr2.cpp: implementation of the Svr2 class.
//
//////////////////////////////////////////////////////////////////////
#include "Svr2.h"
#ifdef __INCPP
Svr2::Svr2(){}
#endif
Svr2::~Svr2(){}
三.测试工程文件:
//////////////////////////////////////////////////////////////////////
// test.cpp: Defines the entry point for the console application.
//
//////////////////////////////////////////////////////////////////////
#define __FLIP_MEM_MANAGER__
#include "ktype.h"
#include "dll/svr1.h"
#include "static/svr2.h"
int main(int argc, char* argv[])
{
        // test dll:
 Svr1 *pSvr1 = new Svr1; // call overload operator new
 delete pSvr1;           // call overload operator delete

 // test static:
 Svr2 *pSvr2 = new Svr2; // call overload operator new
 delete pSvr2;           // whether call overload operator delete depend on Svr2's
                              // construct function if implement in the cpp, if then not,
                           // else call!!!
 // below code will all call overload new and delete
 Svr2 *pOk = ::new Svr2;
 ::delete pOk;
 return 0;
}
四.重载new和delete操作符的头文件
//////////////////////////////////////////////////////////////////////
// ktype.h: Defines the entry point for the console application.
//
//////////////////////////////////////////////////////////////////////
#ifndef  __TYPE_H
#define  __TYPE_H
#include "windows.h"
// 注:此文件仅临时作测试用.
#ifdef __FLIP_MEM_MANAGER__
 static inline void * operator new(size_t size)
 {
  void *p = malloc(size); // (__FILE__, __LINE__)
  OutputDebugString("[Here] overload new\n");
  return p;
 }
 static inline void *operator new[](size_t size)
 {
  void *p = malloc(size); // (__FILE__, __LINE__)
  OutputDebugString("[Here] overload new[]\n");
  return p;
 }
 static inline void operator delete(void *p)
 {
  free(p);
  OutputDebugString("[Here] overload free\n");
 }
 static inline void operator delete[](void *p)
 {
  free(p);
  OutputDebugString("[Here] overload free[]\n");
 }
#endif // __FLIP_MEM_MANAGER__
#endif // __TYPE_H
 
posted on 2010-10-25 09:46  Jacky  阅读(800)  评论(0)    收藏  举报