Thread: free array of array extremely slow

  1. #1
    Registered User
    Join Date
    May 2005
    Posts
    8

    free array of array extremely slow

    hello all,

    i ve created an array of array, and it is VERY fast to allocate with new.

    however, when freeing it with delete, it takes up to 1 minute! i can actually see the size decreasing slowly in the Page File Usage History of the Windows Task Manager (whereas when created it is an almost instant jump in memory size)

    this is the freeing code: (in a destructor)
    Code:
    for (register unsigned short int i = 0; i < wZ; i++)
    {
    	//free the columns of row j, slice i
    	for (register unsigned short int j = 0; j < wY; j++)
    		delete data[i][j];
    
    	//free the rows of slice i
    	delete data[i];
    }
    i m using MSVC++ .NET version.

    i ve been suggested that this could be because the compiler kinds of defragments the memory everytime it frees just one column, whitout realizing that it would eventually free the WHOLE thing anyway...

    any idea to make the delete faster (i hope as fast as when created with new)

    thanks a lot!
    -yves-

  2. #2
    Rabble Rouser Slacker's Avatar
    Join Date
    Dec 2005
    Posts
    116
    Eew, ugly problem. But if you want to go to more work in setting up the allocation, you can cut the deallocation down to two calls to operator delete[]:
    Code:
    // Allocate one big block for data + pointers to act as rows
    T *mem = new T[wZ * wY];
    T **data = new T[wZ];
    
    for ( int i = 0; i < wZ; i++ )
      data[i] = &mem[i * wY];
    Code:
    delete [] data;
    delete [] mem;
    Have you tried working with the standard containers at all to see if their memory handling is more efficient than your hand rolled code?

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Also note that your delete calls are wrong. You should be using delete[] instead of delete in some places depending on how you allocated the arrays. This might not make it go any faster, but it is still a good idea to make it correct first.

    The memory fragmentation thing can be handled with a pool allocator in a standard container, or by taking advantage of the small block heap. A co-worker of mine found an issue where Microsoft turned off their small block heap allocator in Win 2K and later. When he called _set_sbh_threshold(1016) at the beginning of the program to turn that back on, it improved the memory freeing times in the app immensely. You might consider trying this in your app, but I don't have any extra information on other consequences or pitfalls.

  4. #4
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    Your thread made me consider the problem also. Go check out my thread to see if it works for you. Only one new and one delete.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Without knowing how you declared data, it's hard to say.
    To me, it looks like you're deleting each member of the array individually rather than a whole array at once.

    That is,
    delete data[i][j] would be delete [] data[i]
    delete data[i] would be delete [] data;

    Oh, and you definitely don't need the register keyword in there.

  6. #6
    Registered User
    Join Date
    May 2005
    Posts
    8
    makes sense, i should have posted that too:

    Code:
    data = new unsigned char** [wZ]; 
    
    for (i = 0; i < wZ; i++)
    	{
    		data[i] = new unsigned char* [wY];
    
    		for (j = 0; j < wY; j++)		
    			data[i][j] = new unsigned char [cwX];		
    	}
    and why is "register" useless? i thought it was helpful during loops to speed up the code (since it was keeping the value in the register of the processor)

    -yves-

  7. #7
    Rabble Rouser Slacker's Avatar
    Join Date
    Dec 2005
    Posts
    116
    >and why is "register" useless?
    It's only useless on compilers that ignore it.

    >since it was keeping the value in the register of the processor
    Using register is only a hint, one that the compiler can ignore, and almost always does, because register assignment is an optimization that the compiler is better suited to doing than the programmer.

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You have a three dimensional array. Your deletes should look like:
    Code:
    Loop1 {
      Loop 2 {
        delete [] data[i][j];
      }
      delete [] data[i];
    }
    delete [] data;
    See if you still have the slowdown once you fix that code. I'm guessing you might, in which case you can try some of the earlier suggestions.

  9. #9
    Registered User
    Join Date
    May 2005
    Posts
    8
    yup, sorry for that

    i indeed deal with 3D arrays, but i simplified the code i posted (but forgot to do the same for the "new" part of the code that i posted afterwards)

    thanks a lot for all the responses, you ve all been a great help!!
    now my week end is doomed, i ll have to give a shot to all your ideas ;-)

    btw, adding the [] did not change the speed of "delete".... still terribly slow :-(

  10. #10
    Rabble Rouser Slacker's Avatar
    Join Date
    Dec 2005
    Posts
    116
    >btw, adding the [] did not change the speed of "delete".... still terribly slow :-(
    I don't imagine that it did, but it made your code correct where it was otherwise completely undefined. When you allocate memory using operator new[], you have to use operator delete[] to deallocate it or it invokes undefined behavior, which is a synonym for "really really wrong". Likewise, when you allocate a single object with operator new, you have to use operator delete to deallocate it:
    Code:
    char *p = new char[N];
    delete [] p;
    Code:
    char p = new char;
    delete p;
    Match the square brackets and you'll be good.

    Cheers!

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    To allocate a 3D array in only 3 alloc calls
    Code:
    T ***m_buffer = new T**[xMax];
    T  **m_tempxy = new T*[xMax*yMax];
    T   *m_tempxyz = new T[xMax*yMax*zMax];
    for ( int x = 0 ; x < xMax ; x++, m_tempxy += yMax ) {
      m_buffer[x] = m_tempxy;
      for ( int y = 0 ; y < yMax ; y++, m_tempxyz += zMax ) {
        m_buffer[x][y] = m_tempxyz;
      }
    }
    And to get rid of it again
    Code:
    delete [] m_buffer[0][0];
    delete [] m_buffer[0];
    delete [] m_buffer;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 1-D array
    By jack999 in forum C++ Programming
    Replies: 24
    Last Post: 05-12-2006, 07:01 PM
  2. Template Array Class
    By hpy_gilmore8 in forum C++ Programming
    Replies: 15
    Last Post: 04-11-2004, 11:15 PM
  3. Type and nontype parameters w/overloading
    By Mr_LJ in forum C++ Programming
    Replies: 3
    Last Post: 01-02-2004, 01:01 AM
  4. djgpp slow free()
    By CtrlAltKick in forum C Programming
    Replies: 2
    Last Post: 11-19-2002, 03:22 AM
  5. array problems
    By slamit93 in forum C++ Programming
    Replies: 7
    Last Post: 04-25-2002, 01:09 PM