Thread: stringstream and memory crash

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    9

    stringstream and memory crash

    Hi! I've got this function to convert and round some float values passed into it.
    ile_miejsc is optional, set by default to 0.

    Code:
    string roundStr (float liczba, int ile_miejsc)
    {
      string liczbaStr, zera(ile_miejsc, '0');
    
      liczba = liczba * pow(10, ile_miejsc);   //12.345
    
      liczba = int (liczba + 0.5);
    
      liczba = liczba / pow(10, ile_miejsc);
    
      stringstream liczbaStrS;
    
      liczbaStrS << liczba;
      liczbaStr = liczbaStrS.str();
    
      if(int(liczba) % 10 == 0)
    	  liczbaStr.append("." + zera);
      else
      {
    	  string::iterator pos = liczbaStr.end() - liczbaStr.find('.') + 2;
    	  while((*pos) && (*(pos++) != '0'))
    		  liczbaStr.append("0");
      }
    
      return liczbaStr;
    }
    The compiler gives me this:
    *** glibc detected *** /media/disk/c++/projects/akcje2/Debug/akcje2: free(): invalid next size (fast): 0x08e61318 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6[0xb75cfff1]
    /lib/tls/i686/cmov/libc.so.6[0xb75d16f2]
    /lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0xb75d47cd]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb77a76f1]
    /usr/lib/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1d )[0xb778535d]
    /usr/lib/libstdc++.so.6(_ZNSsD1Ev+0x4c)[0xb7786d6c]
    /media/disk/c++/projects/akcje2/Debug/akcje2[0x804a207]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb757bb56]
    /media/disk/c++/projects/akcje2/Debug/akcje2[0x8049421]
    ======= Memory map: ========
    08048000-0804c000 r-xp 00000000 08:21 1745 /media/disk/c++/projects/akcje2/Debug/akcje2
    0804c000-0804d000 r--p 00003000 08:21 1745 /media/disk/c++/projects/akcje2/Debug/akcje2
    0804d000-0804e000 rw-p 00004000 08:21 1745 /media/disk/c++/projects/akcje2/Debug/akcje2
    08e61000-08e82000 rw-p 00000000 00:00 0 [heap]
    b7400000-b7421000 rw-p 00000000 00:00 0
    b7421000-b7500000 ---p 00000000 00:00 0
    b7564000-b7565000 rw-p 00000000 00:00 0
    b7565000-b76a3000 r-xp 00000000 07:00 1174 /lib/tls/i686/cmov/libc-2.10.1.so
    b76a3000-b76a4000 ---p 0013e000 07:00 1174 /lib/tls/i686/cmov/libc-2.10.1.so
    b76a4000-b76a6000 r--p 0013e000 07:00 1174 /lib/tls/i686/cmov/libc-2.10.1.so
    b76a6000-b76a7000 rw-p 00140000 07:00 1174 /lib/tls/i686/cmov/libc-2.10.1.so
    b76a7000-b76aa000 rw-p 00000000 00:00 0
    b76aa000-b76c6000 r-xp 00000000 07:00 3173 /lib/libgcc_s.so.1
    b76c6000-b76c7000 r--p 0001b000 07:00 3173 /lib/libgcc_s.so.1
    b76c7000-b76c8000 rw-p 0001c000 07:00 3173 /lib/libgcc_s.so.1
    b76c8000-b76c9000 rw-p 00000000 00:00 0
    b76c9000-b76ed000 r-xp 00000000 07:00 3407 /lib/tls/i686/cmov/libm-2.10.1.so
    b76ed000-b76ee000 r--p 00023000 07:00 3407 /lib/tls/i686/cmov/libm-2.10.1.so
    b76ee000-b76ef000 rw-p 00024000 07:00 3407 /lib/tls/i686/cmov/libm-2.10.1.so
    b76ef000-b77d5000 r-xp 00000000 07:00 3712 /usr/lib/libstdc++.so.6.0.13
    b77d5000-b77d9000 r--p 000e6000 07:00 3712 /usr/lib/libstdc++.so.6.0.13
    b77d9000-b77da000 rw-p 000ea000 07:00 3712 /usr/lib/libstdc++.so.6.0.13
    b77da000-b77e1000 rw-p 00000000 00:00 0
    b77f5000-b77f8000 rw-p 00000000 00:00 0
    b77f8000-b77f9000 r-xp 00000000 00:00 0 [vdso]
    b77f9000-b7814000 r-xp 00000000 07:00 6988 /lib/ld-2.10.1.so
    b7814000-b7815000 r--p 0001a000 07:00 6988 /lib/ld-2.10.1.so
    b7815000-b7816000 rw-p 0001b000 07:00 6988 /lib/ld-2.10.1.so
    bfca6000-bfcbb000 rw-p 00000000 00:00 0 [stack]
    and prints properly formatted and eventually rounded value:
    Code:
    cout << roundStr(120, 2);         //120.00
    please help me with this
    Last edited by fx69; 02-16-2010 at 05:33 PM. Reason: 'properly formatted' :)

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    The first thing to try is
    Code:
    int main ( ) {
      std::string result = roundStr (120, 2);
      std::cout << result << std::endl;
    }
    There is nothing obviously wrong with that code.
    If this simple test works, then the problem is elsewhere in your code.

    Most likely, you've used some raw char* pointers for some other strings, and your own memory management as well (and got it wrong).

    Crashes like this happen when a problem is noticed.
    When the problem actually happened could have been a long time ago, in another part of the program.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by fx69 View Post
    The compiler gives me this:

    *** debugger output omitted ***
    Stop trying to confuse us! That's the output from a debugger, not from a compiler! If it were a compilation error then you wouldn't be able to turn your code into an exe. In this case the error occurs when running your program, so it's coming from the debugger.

    Your program has corrupted memory. We can't see the problem from that code snippet. Use the process of elimination to find out which piece of code is causing the problem.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Registered User
    Join Date
    Feb 2010
    Posts
    9
    Thank you both for your suggestions. It turned out that if I turn off this code:

    Code:
    theKonto.dodajPapier(FFS);    //FFS is the object of class "papier"
    the function from my first post works fine.

    The definition of konto::dodajPapier:

    Code:
    void konto::dodajPapier(papier &akcja)
    {
    	if(size == 0)             //size is set to 0 by constructor of the class
    	{
    		tabl = new papier[size];
    		tabl = &akcja;
    	}
    	else
    	{
    	tabl = new papier[size];
    	tabl[size] = akcja;
    	}
    
    	size++;
    
    }
    What is wrong here ?

  5. #5
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    void konto::dodajPapier(papier &akcja)
    {
    	if(size == 0)             //size is set to 0 by constructor of the class
    	{
    		tabl = new papier[size];  // allocating an array of zero papier 
    		tabl = &akcja;            // now you overwrite the pointer returned from new, the allocated array is lost
    	}
    	else
    	{
    	tabl = new papier[size]; // allocate an array of size papier
    	tabl[size] = akcja;      // tabl[size] is one past the bounds of tabl	}
    
    	size++;
    }
    When you allocate new space for tabl you have to delete [] the previous one. Before that it would be a good idea to copy the data from the previous to the new array

    Kurt

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > tabl = &akcja; // now you overwrite the pointer returned from new, the allocated array is lost
    Not only is it lost, if you try to do
    delete [ ] tabl;
    then you're well into the area where crashes are exceedingly likely and pretty imminent.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Feb 2010
    Posts
    9
    Thank you very much for your replies I'll rebuild this function later
    Cheers!

  8. #8
    Registered User
    Join Date
    Feb 2010
    Posts
    9
    I changed the function and it seems to work, but the memory corruption still occurs
    Now the code's:
    Code:
    void konto::dodajPapier(papier &akcja)
    {
        // in constructor:    tabl = new papier;
        //                               size set to 0
    	tabl[size] = akcja;
    
    	papier *temp = new papier[++size];
    
    	for(int i = 0; i < size; i++)
    		temp[i] = tabl[i];
    
    	delete [] tabl;
    	tabl = temp;
    
    }
    edit: the solution came to me just after posting here I deallocated memory of only once created array in constructor.
    Well I'm editing my post without checking, but I'm pretty sure it's the reason why it didn't work.
    Last edited by fx69; 02-17-2010 at 04:51 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. stringstream
    By jk1998 in forum C++ Programming
    Replies: 2
    Last Post: 07-27-2007, 06:35 PM
  2. Random memory questions
    By Blackroot in forum Windows Programming
    Replies: 3
    Last Post: 04-04-2007, 09:33 PM