Tuxedo中string导致内存泄漏
对象创建的时候会调用构造函数来初始化对象,对象销毁的时候会调用析构函数。
普通的自动变量(local非static)包含构造函数和析构函数。
当进入变量作用域的时候构造函数被调用,当离开变量作用域的时候析构函数被调用。
当在tuxedo的环境中调用 tpreturn()
或者 tpforward()
函数时,编译器进行了一个non-local的goto (using longjmp(3)),导致自动变量的析构函数没有被调用。
为了避免这个问题,我们应该在服务体中调用直接调用 tpreturn()
或 tpforward()
(而不是在服务体调用的函数中调用这两个函数)。
ps:
1.服务体中不能包含包含析构函数的变量,特别是string变量,这些带析构函数的自动变量需要放到函数调用体中,这样当离开函数的作用域的时候,会析构这些变量。如果在服务体中有string变量,那么随着服务循环会有内存泄漏。
2.自动变量需要被嵌套在服务体函数中的大括号{}包围,大括号需要在调用tpreturn()
或 tpforward()
函数前结束。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#ifdef __cplusplus extern "C" #endif void #if defined(__STDC__) || defined(__cplusplus) SERVICE(TPSVCINFO *rqst) #else SERVICE(rqst) TPSVCINFO *rqst; #endif { string Message; ... tpreturn(TPFAIL, 0, 0, 0L, 0); } |
可以改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#ifdef __cplusplus extern "C" #endif void #if defined(__STDC__) || defined(__cplusplus) SERVICE(TPSVCINFO *rqst) #else SERVICE(rqst) TPSVCINFO *rqst; #endif { do { string Message; ... } while(0); tpreturn(TPSUCCESS, 0,NULL, 0L, 0); } |
附原资料
C++ constructors are called to initialize class objects when those objects are created, and
destructors are invoked when class objects are destroyed.
For automatic (that is, local, non-static) variables that contain constructors and destructors, the constructor is called when the variable comes into scope and the destructor is called when the variable goes out of scope.
However, when you call the tpreturn() or tpforward() function, the compiler performs a non-local goto
(using longjmp(3)) such that destructors for automatic variables are not called.
To avoid this problem, write the application so that you call tpreturn() or tpforward() from the service
routine directly (instead of from any functions that are called from the service routine).
In addition, one of the following should be true:
1 The service routine should not have any automatic variables with destructors (they should
be declared and used in a function called by the service routine).
2 Automatic variables should be declared and used in a nested scope (contained within curly
brackets {}) in such a way that the scope ends before calling the tpreturn() or
tpforward() function.