Patch 7.4.560
Problem:    Memory leak using :wviminfo. Issue 296.
Solution:   Free memory when needed. (idea by Christian Brabandt)
Files:      src/ops.c


*** ../vim-7.4.559/src/ops.c    2014-12-17 18:35:37.553795955 +0100
--- src/ops.c   2014-12-17 20:59:49.722557613 +0100
***************
*** 5663,5668 ****
--- 5663,5670 ----
      int               set_prev = FALSE;
      char_u    *str;
      char_u    **array = NULL;
+     int               new_type;
+     colnr_T   new_width;
  
      /* We only get here (hopefully) if line[0] == '"' */
      str = virp->vir_line + 1;
***************
*** 5695,5715 ****
      limit = 100;      /* Optimized for registers containing <= 100 lines */
      if (do_it)
      {
        if (set_prev)
            y_previous = y_current;
!       vim_free(y_current->y_array);
!       array = y_current->y_array =
!                      (char_u **)alloc((unsigned)(limit * sizeof(char_u *)));
        str = skipwhite(skiptowhite(str));
        if (STRNCMP(str, "CHAR", 4) == 0)
!           y_current->y_type = MCHAR;
        else if (STRNCMP(str, "BLOCK", 5) == 0)
!           y_current->y_type = MBLOCK;
        else
!           y_current->y_type = MLINE;
        /* get the block width; if it's missing we get a zero, which is OK */
        str = skipwhite(skiptowhite(str));
!       y_current->y_width = getdigits(&str);
      }
  
      while (!(eof = viminfo_readline(virp))
--- 5697,5721 ----
      limit = 100;      /* Optimized for registers containing <= 100 lines */
      if (do_it)
      {
+       /*
+        * Build the new register in array[].
+        * y_array is kept as-is until done.
+        * The "do_it" flag is reset when something is wrong, in which case
+        * array[] needs to be freed.
+        */
        if (set_prev)
            y_previous = y_current;
!       array = (char_u **)alloc((unsigned)(limit * sizeof(char_u *)));
        str = skipwhite(skiptowhite(str));
        if (STRNCMP(str, "CHAR", 4) == 0)
!           new_type = MCHAR;
        else if (STRNCMP(str, "BLOCK", 5) == 0)
!           new_type = MBLOCK;
        else
!           new_type = MLINE;
        /* get the block width; if it's missing we get a zero, which is OK */
        str = skipwhite(skiptowhite(str));
!       new_width = getdigits(&str);
      }
  
      while (!(eof = viminfo_readline(virp))
***************
*** 5717,5756 ****
      {
        if (do_it)
        {
!           if (size >= limit)
            {
!               y_current->y_array = (char_u **)
                              alloc((unsigned)(limit * 2 * sizeof(char_u *)));
                for (i = 0; i < limit; i++)
!                   y_current->y_array[i] = array[i];
                vim_free(array);
                limit *= 2;
-               array = y_current->y_array;
            }
            str = viminfo_readstring(virp, 1, TRUE);
            if (str != NULL)
                array[size++] = str;
            else
                do_it = FALSE;
        }
      }
      if (do_it)
      {
        if (size == 0)
        {
-           vim_free(array);
            y_current->y_array = NULL;
        }
!       else if (size < limit)
        {
            y_current->y_array =
                        (char_u **)alloc((unsigned)(size * sizeof(char_u *)));
            for (i = 0; i < size; i++)
!               y_current->y_array[i] = array[i];
!           vim_free(array);
        }
-       y_current->y_size = size;
      }
      return eof;
  }
  
--- 5723,5788 ----
      {
        if (do_it)
        {
!           if (size == limit)
            {
!               char_u **new_array = (char_u **)
                              alloc((unsigned)(limit * 2 * sizeof(char_u *)));
+ 
+               if (new_array == NULL)
+               {
+                   do_it = FALSE;
+                   break;
+               }
                for (i = 0; i < limit; i++)
!                   new_array[i] = array[i];
                vim_free(array);
+               array = new_array;
                limit *= 2;
            }
            str = viminfo_readstring(virp, 1, TRUE);
            if (str != NULL)
                array[size++] = str;
            else
+               /* error, don't store the result */
                do_it = FALSE;
        }
      }
      if (do_it)
      {
+       /* free y_array[] */
+       for (i = 0; i < y_current->y_size; i++)
+           vim_free(y_current->y_array[i]);
+       vim_free(y_current->y_array);
+ 
+       y_current->y_type = new_type;
+       y_current->y_width = new_width;
+       y_current->y_size = size;
        if (size == 0)
        {
            y_current->y_array = NULL;
        }
!       else
        {
+           /* Move the lines from array[] to y_array[]. */
            y_current->y_array =
                        (char_u **)alloc((unsigned)(size * sizeof(char_u *)));
            for (i = 0; i < size; i++)
!           {
!               if (y_current->y_array == NULL)
!                   vim_free(array[i]);
!               else
!                   y_current->y_array[i] = array[i];
!           }
        }
      }
+     else
+     {
+       /* Free array[] if it was filled. */
+       for (i = 0; i < size; i++)
+           vim_free(array[i]);
+     }
+     vim_free(array);
+ 
      return eof;
  }
  
*** ../vim-7.4.559/src/version.c        2014-12-17 18:35:37.553795955 +0100
--- src/version.c       2014-12-17 18:56:33.810259558 +0100
***************
*** 743,744 ****
--- 743,746 ----
  {   /* Add new patch number below this line */
+ /**/
+     560,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
17. You turn on your intercom when leaving the room so you can hear if new
    e-mail arrives.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui