Hi

3 remarks about vim/src/undo.c (at changeset: 271a5907f944):

(1) Using persistent-undo, I notice once in a while the following memory
    leak, but I have not found the way to reproduce it all the time:

==3371== 10 bytes in 2 blocks are definitely lost in loss record 23 of 116
==3371==    at 0x4024F70: malloc (vg_replace_malloc.c:236)
==3371==    by 0x8114F98: lalloc (misc2.c:919)
==3371==    by 0x81BCC06: u_read_undo (undo.c:983)
==3371==    by 0x80C5359: readfile (fileio.c:2591)
==3371==    by 0x8053976: open_buffer (buffer.c:132)
==3371==    by 0x8098ABE: do_ecmd (ex_cmds.c:3658)
==3371==    by 0x80AEF7B: do_exedit (ex_docmd.c:7620)
==3371==    by 0x80AEC38: ex_edit (ex_docmd.c:7516)
==3371==    by 0x80A782C: do_one_cmd (ex_docmd.c:2639)
==3371==    by 0x80A5105: do_cmdline (ex_docmd.c:1108)
==3371==    by 0x812AD39: nv_colon (normal.c:5226)
==3371==    by 0x81245C3: normal_cmd (normal.c:1188)
==3371==    by 0x80E7938: main_loop (main.c:1216)
==3371==    by 0x80E742F: main (main.c:960)

It's this alloc in undo.c:

 983        array = (char_u **)U_ALLOC_LINE(
 984                             (unsigned)(sizeof(char_u *) * uep->ue_size));

Looking at the undo.c code, memory seems to be properly freed
but I might be missing something since Valgrind does not generally
give spurious leak messages.


(2) In vim/src/undo.c  I see at line 92:

 91  /* See below: use malloc()/free() for memory management. */
 92  #define U_USE_MALLOC 1

Whether U_USE_MALLOC is defined or not selects different
implementations of U_FREE_LINE and U_ALLOC_LINE.

Is the implementation when U_USE_MALLOC is undefined
still meant to be used? Or can it be removed?

I'm asking because if I comment out the line #define U_USE_MALLOC 1
at line undo.c:92, then Vim quickly crashes when using persistent-undo.
In other words, persistent undo only works when U_USE_MALLOC is defined.


(3) When U_USE_MALLOC is defined (default behavior), I see that 1 byte
    is added to every allocations at line 117:

 115 #ifdef U_USE_MALLOC
 116 # define U_FREE_LINE(ptr) vim_free(ptr)
 117 # define U_ALLOC_LINE(size) lalloc((long_u)((size) + 1), FALSE)
 118 #else

This extra 1 byte is odd since it's not needed everywhere U_ALLOC_LINE(...)
is used.  I think it's better if the caller is responsible for adding +1
when needed to avoid wasting memory.  Attached patch does that.

Maybe this patch also fixes the leak (1) but I'm not sure since I don't
know how to reproduce it all the time.  At least, I have not seen the
leak  so far after applying the attached patch.

Regards
-- Dominique

-- 
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
diff -r 271a5907f944 src/undo.c
--- a/src/undo.c	Tue May 25 22:09:21 2010 +0200
+++ b/src/undo.c	Tue May 25 23:12:27 2010 +0200
@@ -114,7 +114,7 @@
 
 #ifdef U_USE_MALLOC
 # define U_FREE_LINE(ptr) vim_free(ptr)
-# define U_ALLOC_LINE(size) lalloc((long_u)((size) + 1), FALSE)
+# define U_ALLOC_LINE(size) lalloc((long_u)((size)), FALSE)
 #else
 static void u_free_line __ARGS((char_u *ptr, int keep));
 static char_u *u_alloc_line __ARGS((unsigned size));
@@ -896,7 +896,7 @@
         goto error;
     else if (str_len > 0)
     {
-        if ((line_ptr = U_ALLOC_LINE(str_len)) == NULL)
+        if ((line_ptr = U_ALLOC_LINE(str_len + 1)) == NULL)
             goto error;
         for (i = 0; i < str_len; i++)
             line_ptr[i] = (char_u)getc(fp);
@@ -917,10 +917,13 @@
     /* uhp_table will store the freshly created undo headers we allocate
      * until we insert them into curbuf. The table remains sorted by the
      * sequence numbers of the headers. */
-    uhp_table = (u_header_T **)U_ALLOC_LINE(num_head * sizeof(u_header_T *));
-    if (uhp_table == NULL)
-        goto error;
-    vim_memset(uhp_table, 0, num_head * sizeof(u_header_T *));
+    if (num_head > 0)
+    {
+	uhp_table = (u_header_T **)U_ALLOC_LINE(num_head * sizeof(u_header_T *));
+	if (uhp_table == NULL)
+	    goto error;
+	vim_memset(uhp_table, 0, num_head * sizeof(u_header_T *));
+    }
 
     c = get2c(fp);
     while (c == UF_HEADER_MAGIC)
@@ -980,14 +983,16 @@
             uep->ue_lcount = get4c(fp);
             uep->ue_size = get4c(fp);
             uep->ue_next = NULL;
-            array = (char_u **)U_ALLOC_LINE(
+
+            array = (uep->ue_size == 0)
+            		? NULL : (char_u **)U_ALLOC_LINE(
 				 (unsigned)(sizeof(char_u *) * uep->ue_size));
             for (i = 0; i < uep->ue_size; i++)
             {
                 line_len = get4c(fp);
                 /* U_ALLOC_LINE provides an extra byte for the NUL terminator.*/
                 line = (char_u *)U_ALLOC_LINE(
-				      (unsigned) (sizeof(char_u) * line_len));
+				      (unsigned) (sizeof(char_u) * line_len + 1));
                 if (line == NULL)
                     goto error;
                 for (j = 0; j < line_len; j++)
@@ -1100,8 +1105,7 @@
     goto theend;
 
 error:
-    if (line_ptr != NULL)
-        U_FREE_LINE(line_ptr);
+    U_FREE_LINE(line_ptr);
     if (uhp_table != NULL)
     {
         for (i = 0; i < num_head; i++)
@@ -3074,7 +3078,7 @@
 
     src = ml_get(lnum);
     len = (unsigned)STRLEN(src);
-    if ((dst = U_ALLOC_LINE(len)) != NULL)
+    if ((dst = U_ALLOC_LINE(len + 1)) != NULL)
 	mch_memmove(dst, src, (size_t)(len + 1));
     return (dst);
 }

Raspunde prin e-mail lui