Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: zsh crash in recent -current

    Date:        Wed, 13 Mar 2019 10:37:41 -0700
    From:        Brian Buhrow <>
    Message-ID:  <>

  | Given this code fragment and the discussion you raise
  | about it, allow me to ask what perhaps is a naive question.  If the sample
  | you quote is incorrect, what is the correct way to accomplish the same
  | task?
The basic principle is that once memory is freed it no longer belongs
to the application (while none I have ever seen actually do, the
malloc implementation is free to retrn the memory to the kernel, and
remove it from the process's address space).

So, everything one wants from the memory block needs to be done before
the free() happens.

In cases of muti-threaded applications, including the kernel,
the right answer depends upon just how locking gets done, what
gets locked when, and for how long (need to make sure that the
list isn't being changed by some other thread, or deal with the
possibility that it is, if we cannot reasonably prevent it - in
the worst case, exit the loop and restart from the beginning each
time something happens that requires releasing a lock on the
list itself).

But for a simple single threaded userland application, something

  | } 	for (list_ptr = list_head; list_ptr != NULL; list_ptr = next) {
		next = list_ptr->nxt;
  | } 		/* do stuff on list */
  | } 		if (element_should_be_deleted) {
  | } 			/* with testing for NULLs added but not shown here */
  | } 			list_ptr->prev->nxt = list_ptr->nxt;
  | } 			list_ptr->nxt->prev = list_ptr->prev;
  | } 			free(list_ptr);
  | } 		}
  | } 	}

There are plenty of other (valid) ways to write it of course, but all of
them require that after that "free()" we never touch *list_ptr (aka list_ptr->)
until list_ptr has been changed to refer to something that has not been free'd.


Home | Main Index | Thread Index | Old Index