关于C++的std::queue内存不释放的问题的解决方法

https://blog.csdn.net/zhoukai216/article/details/89403363

最近在使用std::queue的时候,遇到一些奇怪的问题。我们使用std::queue来存放一些临时的缓冲数据,然后有一个线程不断地从queue里取数据,写入到文件中,之后会调用pop()函数将数据弹出。但是很奇怪的地在弹出的过程中,程序的内存占用丝毫没有减少。查了一些资料后发现,貌似std::queue底层自己有一套内存管理机制,只有在程序退出或是queue被销毁的时候才会释放这一部分内存。笔者使用的测试代码如下:

 
  1. #include <stdio.h>

  2.  
  3. #include <queue>

  4.  
  5. #include <WinSock2.h>

  6.  
  7.  
  8.  
  9. template<typename Data>

  10.  
  11. class concurrent_queue

  12.  
  13. {

  14.  
  15. private:

  16.  
  17. std::queue<Data> the_queue;

  18.  
  19. public:

  20.  
  21. void push( const Data& data )

  22.  
  23. {

  24.  
  25. the_queue.push( data );

  26.  
  27. }

  28.  
  29. bool empty( ) const

  30.  
  31. {

  32.  
  33. return the_queue.empty( );

  34.  
  35. }

  36.  
  37. Data& front( )

  38.  
  39. {

  40.  
  41. return the_queue.front( );

  42.  
  43. }

  44.  
  45. Data const& front( ) const

  46.  
  47. {

  48.  
  49. return the_queue.front( );

  50.  
  51. }

  52.  
  53. void pop( )

  54.  
  55. {

  56.  
  57. the_queue.pop( );

  58.  
  59. }

  60.  
  61. int size( )

  62.  
  63. {

  64.  
  65. return the_queue.size( );

  66.  
  67. }

  68.  
  69. };

  70.  
  71.  
  72.  
  73. typedef struct FRAME

  74.  
  75. {

  76.  
  77. unsigned char* sPbuf;

  78.  
  79. int iSize;

  80.  
  81. };

  82.  
  83.  
  84.  
  85. int main() {

  86.  
  87. concurrent_queue<FRAME> frame_list;

  88.  
  89. FRAME f;

  90.  
  91.  
  92.  
  93. // push

  94.  
  95. for (int i = 0; i < 100000; i ++ ) {

  96.  
  97. FRAME f;

  98.  
  99. f.sPbuf = NULL;

  100.  
  101. f.sPbuf = new byte[ 1000 ];

  102.  
  103. f.iSize = 1000;

  104.  
  105. frame_list.push( f );

  106.  
  107. }

  108.  
  109. // pop

  110.  
  111. for (int i = 0; i < 100000; i ++ ) {

  112.  
  113. FRAME f2 = frame_list.front( );

  114.  
  115. delete [] f2.sPbuf;

  116.  
  117. f2.sPbuf = NULL;

  118.  
  119. frame_list.pop( );

  120.  
  121. Sleep(10);

  122.  
  123. printf("%d\n",i);

  124.  
  125.  
  126.  
  127. }

  128.  
  129. return 0;

  130.  
  131. }

在VS2010中编译并运行上面的代码时,发现随着pop()的调用,内存占用并没有减少。解决方法有以下几种:

l 使用list来替代queue,经测试是可行的,在pop的时候内存会减少。但是list的效率要远不如queue了。

l 考虑使用别的编译器,例如gcc,内存也会正常地减少。

l 自己写一个Queue。

贴出一个可以正常减少内存的自定义的Queue代码:

 
  1. template<typename Data>

  2.  
  3. class concurrent_queue

  4.  
  5. {

  6.  
  7. private:

  8.  
  9. int _size;

  10.  
  11. struct queue_block

  12.  
  13. {

  14.  
  15. Data q[ 0x40 ];

  16.  
  17. unsigned short head, tail;

  18.  
  19. queue_block *next;

  20.  
  21. queue_block( ) { head = tail = 0; next = NULL; }

  22.  
  23. };

  24.  
  25. queue_block *head, *tail;

  26.  
  27.  
  28.  
  29. mutable boost::mutex the_mutex;

  30.  
  31. public:

  32.  
  33.  
  34.  
  35. concurrent_queue( ) { head = tail = NULL; }

  36.  
  37. ~concurrent_queue( )

  38.  
  39. {

  40.  
  41. while ( head )

  42.  
  43. {

  44.  
  45. queue_block *p = head;

  46.  
  47. head = head->next;

  48.  
  49. delete p;

  50.  
  51. }

  52.  
  53. }

  54.  
  55. void push( const Data& data )

  56.  
  57. {

  58.  
  59. boost::mutex::scoped_lock lock( the_mutex );

  60.  
  61. if ( !head )

  62.  
  63. head = tail = new queue_block;

  64.  
  65. if ( ( ( tail->tail + 1 ) & 0x3f ) == tail->head )

  66.  
  67. {

  68.  
  69. tail->next = new queue_block;

  70.  
  71. tail = tail->next;

  72.  
  73. }

  74.  
  75. tail->q[ tail->tail ] = data;

  76.  
  77. tail->tail = ( tail->tail + 1 ) & 0x3f;

  78.  
  79. _size ++;

  80.  
  81. }

  82.  
  83. bool empty( ) const

  84.  
  85. {

  86.  
  87. boost::mutex::scoped_lock lock( the_mutex );

  88.  
  89. return head == NULL;

  90.  
  91. }

  92.  
  93. Data& front( )

  94.  
  95. {

  96.  
  97. boost::mutex::scoped_lock lock( the_mutex );

  98.  
  99. return head->q[ head->head ];

  100.  
  101. }

  102.  
  103. Data const& front( ) const

  104.  
  105. {

  106.  
  107. boost::mutex::scoped_lock lock( the_mutex );

  108.  
  109. return head->q[ head->head ];

  110.  
  111. }

  112.  
  113. void pop( )

  114.  
  115. {

  116.  
  117. boost::mutex::scoped_lock lock( the_mutex );

  118.  
  119. head->head = ( head->head + 1 ) & 0x3f;

  120.  
  121. if ( head->head == head->tail )

  122.  
  123. {

  124.  
  125. queue_block *p = head;

  126.  
  127. head = head->next;

  128.  
  129. delete p;

  130.  
  131. }

  132.  
  133. _size --;

  134.  
  135. }

  136.  
  137. int size( )

  138.  
  139. {

  140.  
  141. boost::mutex::scoped_lock lock( the_mutex );

  142.  
  143. return _size;

  144.  
  145. }

  146.  
  147. };

此文章转载自http://blog.sina.com.cn/s/blog_3fe961ae0101gef9.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值