我爱电脑技术论坛's Archiver

不和人说话 发表于 2008-4-4 11:54

为C++标准库容器写自己的内存分配程序

根据sgi 的STL源码的二级分配算法改写的内存池分配程序,只要稍微修改就可以实现共享内存方式管理,使用C++标准库容器中的map,set,multimap,multiset测试通过,vector测试通不过,原因是在内存回收的时候考虑的比较简单,vector每次分配内存个数不固定,回收也不固定,这样的话,程序还需要继续完善。
]ekFT!C0b:v` Z{:L2b&x%f{o?C
  内存池管理程序源码如下:'G4E7i f#X@-v

"V'D(]\1U 以下是引用片段: [Cob0O Xs
#ifndef MY_ALLOCATOR_H_ !iS*J]$T
#define MY_ALLOCATOR_H_
2nuAC'[D9J #include "stdafx.h" CQ @ G$t/vE5F;J.l
#include <limits> ? c]+S-ly
#include <iostream> l$k(dbL[-IF*D%J
namespace happyever  
J3_5]{V+fS { R/QfGjl,F9g
  enum { NODENUMS = 2 };
x5g#T5i;BnP   union _Obj  
J}5cX+IJ cE   { Y b+F$T4s~
    union _Obj* M_free_list_link; h,g$T O7k|'d\
    char M_client_data[1];     c,g I3@ M N7Hz
  } ;
2ggmA+v.F!d   typedef union _Obj Obj;
vDnDN+GQL/z:P   struct _Cookie
ftCj&Mn   { 2i$xmaF.\*n8i
    int iShmKey;        /* 共享内存键值 */
5T9ai'|L lP]     int iShmID;         /* iShmKey对应的shmid */ xL,y0|*R9U
    int iSemKey;        /* 锁信号键值 */
3Z||RO3i6g#B.`     int iSemID;         /* 锁信号标识 */
2q[aWChX+W     int iTotalsize;    /* 容器总容量 */ o+qTA2k#t
    void* pStartall;   /* 共享内存自身地址 */ I7L'X0d0b0i f
    char* pStartfree;  /* 自由空间的开始地址*/
z#Q7ASM'JW%x     char* pEndfree;    /* 自由空间的结束地址*/ g Q:XxdsYlT
    int iUseNum[NODENUMS]; w6MK B@)je
    /*用来存放free_list中节点的size*/ .h GO3l*_:j
    short sFreelistIndex[NODENUMS];
:xsJ%K3X6UP     /*存放分配内存节点的链表*/ sp!J w\R
    Obj* uFreelist[NODENUMS];
@*Lq3BU8ud   };
9D s0p[WA\9pI   typedef struct _Cookie Cookie; (KL| Z m1Z
  //Obj; &q2B,k?H8|(C-e
  //Cookie; q$? CrW
  static Cookie *pHead = NULL;
0s1u#k|%rv6OR   template <class T>
-o9MCN1d B ihK O9o   class MyAlloc  -~/c7H2fT3Veq\
  {
.s"`I!_7A\Y   private: #R'FI/](_CH^ b!o`)y
    static const int ALIGN = sizeof(Obj); WK|x/lx` u+YN'S b
    int round_up(int bytes);
q~7`i:x;KOnq     int freelist_index(int bytes);
n1Zs4W3p7Q     int freelist_getindex(int bytes);
x5Wm4Qpl1o8tX*u     char* chunk_alloc(int size, int *nobjs); 1dnB6u q+a)K
    void* refill(int num,int n);
N|Ke8N W   public:
c9h:w&BC     // type definitions
Tlc nw&R9ju     typedef T        value_type;
.|c-E@0s"b5UF     typedef T*       pointer;
Q0L"bT Qu.l0|!P     typedef const T* const_pointer;
0`(W0c)z;cI s     typedef T&       reference; wM9b9M%\
    typedef const T& const_reference; n._SIb)l
    typedef std::size_t    size_type; ~$XHE1i B-P*h~V
    typedef std::ptrdiff_t difference_type; -G|Hx"^zo
    template <class U>
3\F"XzQ/m'R     struct rebind  
#c9j*R1S4P.MV DL     {
m*LZ;fI6[       typedef MyAlloc<U> other; $I{!p4pFF
    }; 3]4uzs-X"t6Ev
    pointer address (reference value) const  
([#E`xC~6L5c3Md     {
,? N%~c g _8?6l       return &value;
PdMc$|%V&ms     }
.j;z!VkX     const_pointer address (const_reference value) const  
8`e_DB BG C     { 4c^NCY:|&E_h.^
      return &value; k&HLKWTQ;?K5H
    }
RIm@\B;rr9H }     MyAlloc() throw()  
M9a G*bD;[9FM     { i4}Dh1X \
      std::cout<<"MyAlloc"<<std::endl; "A)K3f9y0^7t(r"C
    }
Gh2wmnj~fO@*U.]     MyAlloc(const MyAlloc& x) throw()  $alR s7p
    { _ n0V.@d']k
      std::cout<<"const MyAlloc"<<std::endl; -v:Q@AzyTN3T
    }
`n%| @B~kD     template <class U> +f&ZMi}
    MyAlloc (const MyAlloc<U>& x) throw() BrKL j.^gJ
    {
6v7?FzT[mb       std::cout<<"const MyAlloc<U>"<<std::endl; 0Jj)@ lt
    } \LfP(p6JQ
    ~MyAlloc() throw()  QVYIq!ui1N
    { |%sfaa6`5m(L9T
      std::cout<<"~MyAlloc"<<std::endl;
D/w_ Gc?,u'q     } T| }K _ T1E
    size_type max_size () const throw()  
d F:` s;aj7v     { ovU`Q:c
      return std::numeric_limits<std::size_t>::max() / sizeof(T);
/G`f6w!e.a W     }
D^_ H!k X)e&V!`     //void PrintFreelistAndCookie(); 3oa1Q.}/YZ"hh0q+X1l
    pointer allocate (size_type num, const void* = 0)  
1P7h+sN@)r     {
0V]D`2P%~-DY%e       pointer ret = 0;
g_0W6LJ"v       Obj** my_free_list; n1k[:U_@B
      Obj* result;
'BjJU&C       int index; 0A3p!HX5Fw7E2_:c!|a
      // print message and allocate memory with global new
YK%v[N9W       std::cerr << "allocate " << num << " element(s)"
)Q1{0Stuu r         << " of size " << sizeof(T) << std::endl; 3Id C/c8]5gk~s\
      index = freelist_index(sizeof(T));
L8{;}i4d u%RUq       if(index >= NODENUMS)
/z&TvH0}r @       {
{7kbyX         return NULL;
3Pg`Cp)~(Tf9G       }
2U:bg9E |s       my_free_list = pHead->uFreelist + index;
/jqDSYDB.z       //Lock(semid,LOCK_NUM); '\QD5W Ebwrzh
      result = *my_free_list; [&mi?Wb
      if (result == 0) ^.a$w@ yh
      {
l~@g6r?x G|w         ret = (pointer)refill((int)num, round_up(sizeof(T)));
:d9H2N(xP#Yjv       } s \)e.b)U:HBk+k;\ n
      else
t1fDX7P/r       {
'b(@aM SLUj4o         *my_free_list = result->M_free_list_link;
-N#{:TdQ.a \9x         ret = (pointer)result;
E&Nj0Y,}+Vd       } 2N5` ^'L6V'u0uh OG
      //UnLock(semid,LOCK_NUM); I:s8W%a@u*W/H
      pHead->iUseNum[index] = pHead->iUseNum[index] + (int)num; /?:X{hKY$g6[ h7L
      if(0 == ret)
zWK.\_p       { "} \-Vij4R(C
        std::cerr << "alloc memory fail!" << std::endl;
'Ml(c#y4K%s-Pc         exit(1);
Y/L,KoTO _D       }
?*LJ(Suv7wD5u       std::cerr << " allocated at: " << (void*)ret << std::endl;
{.rw [%HU       PrintFreelistAndCookie(); l/po;Q[ @ z*R O
      return ret; %LL&a3L#|DK} F
    }
(E$y/`Vmy$H     void construct (pointer p, const T& value)  
1zfUKiZz A     { ,N Ebs4Z_
      // initialize memory with placement new B'uT3Pr9A F&b#in
      new((void*)p)T(value); 6\?aU/R%z
    }
%~)NI:D Zt     void destroy (pointer p)  
b r R4HZ E     { /e(}"dPK&W]Q
      // destroy objects by calling their destructor 0\ Lw f&F?7z
      p->~T(); bBelL.UFQ$r
    } 8K1r%z La$}W}N
    void deallocate (pointer p, size_type num)  
DM]1z&vL5{$uR$MQ     {
*_5yD:x0`p       Obj** my_free_list;
]:R!M_`)z`l]       Obj* q ;
4gH%vU.hwdF       int index; 9o7AH Byr?!]3e
      index = freelist_getindex(sizeof(T));
${ W)Gc/W5D/s9|C       if(index >= NODENUMS)
2q6L&]'s+Oh       {
3r!zs"FG-J Lq.L X         std::cerr << "deallocate memory fail!" << std::endl;
` ywq7A*b ^3q         exit(1); Y2Xb V1x N-~!u-{K
      }
i5uq.\4^;A8k.Q-n       my_free_list = pHead->uFreelist + index;
_1j B$D8G;R       q = (Obj*) p; ]b6fo7^Y"P
      //Lock(semid,LOCK_NUM);
x/i.nl ha       /*这个地方可能会有问题*/ UR`po}z
      //for(int i=0 ;i<(int)num ; i++)
ZI\$Y'C8a7h       { 5ZA}O DX&B
        q->M_free_list_link = *my_free_list;
&YS*{Cf ec         *my_free_list = q;
O A-A3L8E.N8f       }
vA"t7K*J6@vD       //UnLock(semid,LOCK_NUM); X}he(M,u
      pHead->iUseNum[index] = pHead->iUseNum[index] - (int)num;
7Vv^L J"K6\v       
X1hECb       std::cerr << "deallocate " << num << " element(s)"
!ov5c)|:}S bu         << " of size " << sizeof(T)
:P-_&x(N@[ lrF0vA         << " at: " << (void*)p << std::endl; jF)vZ4N5I5bLe
      PrintFreelistAndCookie(); "Ep{"K%kGw0h:R$O%f
    }
9Z%Hf&`.M   };
*S2~7w-j/s*F   template <class T> iv5wm\K3|{ V4D"n
  int MyAlloc<T>::round_up(int bytes)
m kuF2f-] H!A JY   {
{9a^9aKv-aF T#T     int i;
L*]8T}4Z"\r&y     i = bytes;
6|a+|/`N#L     if(bytes < ALIGN) I`P K[
    { [*Xq |[ jF6T
      i = ALIGN; K3P4EX"EQ
    }
+Y?\z'S     std::cout<<"round_up:bytes="<<bytes<<" , return="<<i<<std::endl;
3| Rx,H5_6~     return i; 7yt#x'[ox
  }; yF vmq*H\S&n3_,_
  template <class T> H {6W9w#R
  int MyAlloc<T>::freelist_index(int bytes)
)mu1ZDb1J   { *u:k(@Q y"Z)XJy
    int i; o[+I;jw H-md4S
    for(i=0 ; i< NODENUMS ; i++) q*p~[*D/x0N@y
    { w/_ eK}iT
      if(pHead->sFreelistIndex[i] == bytes)
N)\B|w'bc8{         break;
p${7]3x+m;QU-EjI k [     } R2Fg)T"[
    if(i >= NODENUMS) 9E!U| V ]
    {
:feri._1q%Y2m)T       for(i=0 ; i< NODENUMS ; i++) B5u4]"v2g:XqB
      { ,L(dqW:\%D9H}J
        if(pHead->sFreelistIndex[i] == 0) E_.I,E i_
        { /a:q*Ui7tfqD
          pHead->sFreelistIndex[i] = bytes; E D9k8q/~:ld+H|
          std::cout<<"freelist_index:bytes="<<bytes<<" , return="<<i<<std::endl; z)M5B#x!Q
          return i; ,\1c/g6k {3^
        } 2aJN ufNW
      } 8m h(y~Q$Ha
    } d\H H%g5s6? jI
    std::cout<<"freelist_index:bytes="<<bytes<<" , return="<<i<<std::endl;
INwc Shtd     return i; /e2Q?t1_
  }; JCIY1S'u
  template <class T> .F0K8^-e*mDm%R
  int MyAlloc<T>::freelist_getindex(int bytes) J2GB+S cNs
  {
!X.n\9}"W7H     int i; 4UtX"s1s
    for(i=0 ; i< NODENUMS ; i++)
B&J(w,Y},OEXO-v     { 0O D/mY(h
      if(pHead->sFreelistIndex[i] == bytes)
7lW Wy)Y"V6Won3k         break;
f"pr6{\5t     }
w7HP"E Dg*D     std::cout<<"freelist_getindex:bytes="<<bytes<<" , return="<<i<<std::endl; o&z rR,mV6K
    return i;
(PfVXv9H   }; hk$t*a1]I#|H bQ
  template <class T> (k)_'m s-D*N8|/wIU
  char* MyAlloc<T>::chunk_alloc(int size, int *nobjs)
5Gtya2\FKA;|.nQ   { ln i$Iz"w B"?@Z
    char* result; YAB$xKM@#F
    int counts = *nobjs;
,r#O c3h4cf     int total_bytes = size * counts; (w!G:Fi%n|7u}
    int bytes_left = int(pHead->pEndfree - pHead->pStartfree); &{Jlg)F*~
    std::cout<<"chunk_alloc:total_bytes = "<<total_bytes Vo/xo,i m8p`
      <<",bytes_left = "<<bytes_left<<std::endl;
5z,Z-^(W b     if (bytes_left >= total_bytes) 8Ug/?2uT-U
    {
bL5n:UB L       result = pHead->pStartfree; '|;n:P'A} Q)z1ue
      pHead->pStartfree += total_bytes;
!Ay$y.MR xx/E       std::cout<<"chunk_alloc:total_bytes = "<<total_bytes
l-Z{-d8v         <<",result = "<<*result<<",start_free = "<<&(pHead->pStartfree)<<std::endl; 3M9}:^:W,p1_$H^o
    }
wKh3j4S;Q:Y&X     else if (bytes_left >= size)
;? |y%^s     { *Y F'x_ f%W Dz
      counts = bytes_left/size;
W_P/q5L&H:cC+P6{I       total_bytes = size * counts;
(h[X]yTO mB       result = pHead->pStartfree;
Z.M:o)@h:yT&N       pHead->pStartfree += total_bytes; DK D3Wzq'u7}I y
      *nobjs = counts; ad)`~3^W-D0X
      std::cout<<"chunk_alloc:total_bytes = "<<total_bytes<<",nobjs = "<<nobjs
(UN0Y&YYr&SZ]         <<",result = "<<*result<<",start_free = "<<&(pHead->pStartfree)<<std::endl; oJr'l?4?_
    } ,KFjWO#Q Ui0x
    else
7L/~UWZn Cp6pzm     {
kt$n j@|       /*还需要处理回收其他空闲freelist里面的空间*/
ucQG6BnJH       result = NULL; Zyx!gV
    } d8F.pDp'_W
    return(result);
#X;E&A(wXe{N/]   };
!J}|r~%i r-{N:^I   template <class T>
0FA YpvmqbJG)I   void* MyAlloc<T>::refill(int num,int n) RP` rEu
  { \~;N$}@q%JFTL
    int counts = num;
"SA*|"N3N"Ei!F     int *nobjs = &counts;
$Yl,pvf`k;J     char* chunk; MT%a}:E#C
    Obj** my_free_list; ld~*G iO9^(E$v
    Obj* result;
LP\6N X9ACN     Obj* current_obj; J6Wpp(N;\'b$d
    Obj* next_obj;
W'O0^1{4aPC]     int i;
`;g;i iU{m+S     chunk = chunk_alloc(n, nobjs); Kbnx H6N6E+O`+e
    if(chunk == NULL)
Ynt [U%r3m#J*a+B\|     { Jk+j Vl [ Z
      return(chunk); Y!{!s*M#_AM8l
    }
Zk*y&xdy&F J     counts = *nobjs;
Z[$hR{i L     if (1 == counts)
%AY h7j'@.f XF     { V_9pL3e*bA
      return(chunk); V,lc(C-`Z
    }
%i,wju7Ed-YP)Z F     my_free_list = pHead->uFreelist + freelist_index(n); &Dj _yp*F?;}k
    result = (Obj*)chunk;
x8pD [z+m6g     *my_free_list = next_obj = (Obj*)(chunk + n*num); 3Ow!mL c_Qm
    for (i = 1; ; i++)
3F;?5L7N v     {
G@1VhA.q9Ic8YA e       current_obj = next_obj; 9hD5nxV?\m
      next_obj = (Obj*)((char*)next_obj + n); !Q#snaE{6BT U
      if (counts - 1 == i)
G#aMr:c       {
};f3R"h}.t         current_obj->M_free_list_link = 0; 4U2l(^o.},J
        break; yzG'Y3GT,Q)RYU
      } ~J4I"Bg LMzt
      else
7MUB/M J%y\s       {
{nZu3pL$X         current_obj->M_free_list_link = next_obj; $y+oJ%x]]}
      } M?"`h0T{ ye4x
    }
.p6lv,^/H{ N     return(result);
Q9O*M f u E,n] F   }; el8^H9O3R
/*这个函数可以改写成自己的共享内存分配函数*/   ^/@Ioy#H(u t
static void InitShm()
(l&a0Bd6p   { ?2w*D?v&NO8H0F
    int i,size=1000;
;U:Om;yR ` { P+?K     pHead = (Cookie*)malloc(sizeof(Cookie)+size); E4@*]?b9ZG#t
    pHead->iTotalsize = sizeof(Cookie)+size; 'g/o!Q*FKR9k;m
    pHead->pStartall  = pHead; .IAWD.?#j+N"B ~l
    pHead->pStartfree = (char*)pHead + sizeof(Cookie); *X W1k&yM9}^$ygD2W
    pHead->pEndfree   = (char*)pHead + pHead->iTotalsize; Wh.\&X;yH.jU
    for(i=0 ; i <NODENUMS ; i++)
V/W U-r8v'tE.h     {
!xp N3?$Hs%r8X       pHead->sFreelistIndex[i]=0; 6U"t$q3b |\X-O!dB+H H
      pHead->uFreelist[i]=0;
8j5T l3b2fG? \       pHead->iUseNum[i]=0; gz E2t p:hC9C1n
    } #w h*y[)AQ'C3ug
  }
zj7j,WhG2F Y   static void PrintFreelistAndCookie()
'q1YnBJC   { ,h6|T%P6x/w3l$POV
    int i,j; -X~8\7\8} N1y#?.Q{,wy2Y#f
    Obj* my_free_list;
5lCJn^RXBdTQ3]s     std::cout<<"Cookie info :"<<std::endl;
aU;Ys.@cy9YL     std::cout<<"sizeof(struct Cookie) = "<<sizeof(Cookie)<<std::endl; uQyB_$J:E
    std::cout<<"Totalsize     = "<<pHead->iTotalsize<<std::endl; dp!~Pmn
    std::cout<<"UsedSize      = "<<int(pHead->pStartfree-(char*)pHead)<<std::endl; bo(}{.z0b
    std::cout<<"FreepoolSize  = "<<int(pHead->pEndfree - pHead->pStartfree)<<std::endl;
C#s5e-I ]#h+Oe$jH     std::cout<<"Startall      = "<<&(pHead->pStartall)<<std::endl; j/R*M"x4JX'l
    std::cout<<"Startfree     = "<<&(pHead->pStartfree)<<std::endl; H)zIuc~%s#m
    std::cout<<"Endfree       = "<<&(pHead->pEndfree)<<std::endl;
t&T'\Rtm{@-c n     std::cout<<"nFreelist info :"<<std::endl;
?W1B&@5z n5Yt\     for(i=0 ; i<NODENUMS ; i++) y?K8?n-HX}7YQ
    {
q }:|6o NET.s.S       j=0; 7i3w%T1mJX(`:y.z
      std::cout<<"iUseNum["<<i<<"] = "<<pHead->iUseNum[i]<<std::endl;
f8bo0r W,l       std::cout<<"FreelistIndex["<<i<<"] = "<<pHead->sFreelistIndex[i]<<std::endl;
S8qJ r$u       my_free_list = pHead->uFreelist[i]; p9@%l7z#?)_&a
      if(my_free_list->M_client_data != 0)
@&@/j.N ~\zG0c       { d |kd M!TYdD
        while(my_free_list->M_client_data != 0)
Q!H?,f;p0s1x4R         { tvzw"PE
          j++;
OYrzb-n{#ZacA           my_free_list = my_free_list->M_free_list_link;
S PD-kyl%yu         } .Aqp)c.x0oh
        std::cout<<"free_list["<<i<<"]; node counts="<<j<<std::endl; j-B.C'P(f9Hx I5z%nFWz
      } F)F;{ cQ1x6n[#U
    } "zO{6W,Zba
  } `G^ rY E,of
  template <class T1, class T2>
aJj4T"`i$BMd   bool operator== (const MyAlloc<T1>&,const MyAlloc<T2>&) throw()  
fc"ah;z&[   {
;g+\Gf @3`O-I E y&s     return true;
4Jd n0N2CJ^3bh   }
/y3f ^x[4m4mD   template <class T1, class T2>
_#lN0~_$j2N$k B `.~   bool operator!= (const MyAlloc<T1>&,const MyAlloc<T2>&) throw()  s x:p'AI)Jn#_
  { ,uTI,MW
    return false; .vM,G8Ye'L5fE
  } )i8Y?[%a6r
}
Xt7J"D)`^(T+j #endif /*MY_ALLOCATOR_H_*/ 8qX4PAAE3IN%D
测试程序的源码如下: *t:a ^,CM,_ S

cGS-~#ei5} y // MyStl.cpp : 定义控制台应用程序的入口点。
-dj%?/\0U8|8B:F //
8{|1O&P!pxaO #include "stdafx.h" 0PNnH(I7i"}
#include <map> !Ql-s)~@:P3l
#include <vector>
8ySn!m4C@ #include <string> N$P:R/~F/H$`1kU'T
#include <utility>
)eV"\Yd1y|9t j+S #include <iostream>
A)[_,AN$ka:G #include "MyAlloc.h" g Lu/v_!z [G
using namespace std;
_@ T$K9al\4Z3Z int _tmain(int argc, _TCHAR* argv[])
,a4y/v`h2@/Ni {
MF9HNu   happyever ::InitShm();
4R;}+bB#upl4zD ?|   multimap<string,int,less<string>,happyever ::MyAlloc<string> > m; C qglcq\D
  m.insert(make_pair(string("Harry"), 32)); U.Iw+Z3|8b8h2U4n0o(c
  m.insert(make_pair(string("Mary"), 59)); 4C9x"Y8NU?*L,?f1Yo
  m.insert(make_pair(string("Roger"), 18));
'y8m"B/F3c A2iYw   m.insert(make_pair(string("Nancy"), 37)); ? q+\7M!q9zS
  m.insert(make_pair(string("Mary"), 23));
,y N!G Ha~&q    u[&W(Z-A A'y7E `J2g
  typedef multimap<string,int,less<string>,happyever ::MyAlloc<string> >::iterator Iter;
V"ie^}4sA   for (Iter p = m.begin(); p != m.end(); p++)
c4nXKN   { .[&a0m(T7C\OD?tP _
    cout << p->first << "," << p->second << endl;
}i6|uSx |fY   }
'UU[ i!|3jo)\   Iter p = m.find("Harry"); Sl,PJ LZ4H1X?qG
  m.erase(p);
-WocCWz.OgI   /*p = m.find("Harry");
f s2KCm#m KvPW   cout << "Harry is: " << p->second << "." << endl;*/
!E"p%VO R4fd-vJ F&{
Q&L9mNI   for (Iter p = m.begin(); p != m.end(); p++)
y"kS5sq `"H1H)L7S   {
,d1vCs}     cout << p->first << "," << p->second << endl; f[j"o2d({PR1w(x
  }
$B7jUI3~F    w8jv WP{8j4i M5`6K3z
  return 0; Jv-o[e6o |S7}
} /o7Oez3m;q
以上程序在vs2005,vc6上测试通过。使用MinGW编译的时候只需要去掉vc的预编译头文件 m3l6nzx%Oc Ul
#include "stdafx.h" %yNQg {!vY R)dr
^o~*w!\ m

h#b6^0lPe{c   即可。
[y0\bt Y X
Rr$\C]jIPx$j   以上程序只要稍微修改,就可以实现共享内存的管理,可以方便的使用标准库提供的容器。加上信号量的锁机制。1r BSYk#e$Zi3~t)jk#D
@-Hr;_3w o1\
  以上为了学习而改写的SGI的stl二级分配算法实现的。以上代码存在一定的局限性。我另外完整实现了共享内存管理的STL标准的alloctor程序,使用posix信号量加锁。目前应用在aix的xlC编译环境下。因为源码涉及公司的商业秘密,所以不能公开。但基本上以上源码已经体现了自己管理内存的完整思路,供这方面需求的朋友一起学习研究用。

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.