bright's profileBright MomentPhotosBlogLists Tools Help

Blog


    April 14

    为什么不能重现关于STL stringstream的bug

    最近运行程序时,发现内存持续增长,原来以为是程序正常的需要,后来经过计算我根本用不了那么多内存,所以是内存泄露,由于我的代码中没有使用任何的new or delete,因此排出我自己代码的问题,最后定位到一个函数,其中使用了stringstream(以前知道它在跨平台时可能存在着问题),我用普通的string间接地替换掉了stringstream,内存果然不再泄漏。于是把全部的stringstream替换掉,程序正常运行,内存的使用保持的很平稳。
    为了证实stringstream存在内存泄露的问题,编写了简单的代码用以验证,但是脱离了我原来的程序之后,就不再发生内存泄露了,感觉非常奇怪。网上google了一下,发现别人也遇到过类似的问题,例如:
    【1】http://tag.csdn.net/Article/c0084395-c30e-47a6-8a61-b14228f87f7e.html
    【2】http://www.it130.cn/Article/FAQ/bianchengyuyan/C-C++/2007-3-7/2007030715022910.html
    但是为什么我不能再现这个bug呢,感觉也不是我的程序的问题,那么问题究竟出自哪?谁能告诉我,不胜感激!
    环境:windows xp sp2 + visual studio.net 2005

    Comments (2)

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    bright liwrote:
    绝对是个bug,不可能为了“效率”,就要泄露内存,而且不一定是为了效率。
    July 14
    bytewrote:
    Bright...通知你一下,本文指向的两个链接已经无效了。
    另外,关于stringstream失效的问题,可以参考下面的文字:

        stringstream是个好东西,网上有不少文章,讨论如何用它实现各种数据类型的转换(比如把double或int转换为string类型)。但如果stringstream使用不当,当心内存出问题(我就吃过亏^_^)。

        试试下面的代码,运行程序前打开任务管理器,过不了几十秒,所有的内存都将被耗尽!

    #include <cstdlib>
    #include <iostream>
    #include <sstream>

    using namespace std;

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    int main(int argc, char *argv[])
    {
       std::stringstream stream;
       string str;

    while(1)
    {   
        //clear(),这个名字让很多人想当然地认为它会清除流的内容。

        //实际上,它并不清空任何内容,它只是重置了流的状态标志而已!
        stream.clear();
      

         // 去掉下面这行注释,清空stringstream的缓冲,每次循环内存消耗将不再增加!
         //stream.str("");
         

         stream<<"sdfsdfdsfsadfsdafsdfsdgsdgsdgsadgdsgsdagasdgsdagsadgsdgsgdsagsadgs";
        stream>>str;
       

          // 去掉下面两行注释,看看每次循环,你的内存消耗增加了多少!
          //cout<<"Size of stream = "<<stream.str().length()<<endl;
          //system("PAUSE");
    }

    system("PAUSE");
    return EXIT_SUCCESS;

    }

        把stream.str("");   那一行的注释去掉,再运行程序,内存就正常了

        看来stringstream似乎不打算主动释放内存(或许是为了提高效率),但如果你要在程序中用同一个流,反复读写大量的数据,将会造成大量的内存消耗,因些这时候,需要适时地清除一下缓冲 (用 stream.str("") )。

        另外不要企图用 stream.str().resize(0),或 stream.str().clear() 来清除缓冲,使用它们似乎可以让stringstream的内存消耗不要增长得那么快,但仍然不能达到清除stringstream缓冲的效果(不信做个 实验就知道了,内存的消耗还在缓慢的增长!),至于stream.flush(),则根本就起不到任何作用。


    July 11

    Trackbacks

    The trackback URL for this entry is:
    http://bright-li.spaces.live.com/blog/cns!64A26545E8622B86!508.trak
    Weblogs that reference this entry
    • None