Blame programming-guidelines/pt_BR/memory-management.page

Packit 1470ea
Packit 1470ea
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="topic" id="memory-management" xml:lang="pt-BR">
Packit 1470ea
Packit 1470ea
  <info>
Packit 1470ea
    <link type="guide" xref="index#general-guidelines"/>
Packit 1470ea
Packit 1470ea
    <credit type="author copyright">
Packit 1470ea
      <name>Philip Withnall</name>
Packit 1470ea
      <email its:translate="no">philip.withnall@collabora.co.uk</email>
Packit 1470ea
      <years>2015</years>
Packit 1470ea
    </credit>
Packit 1470ea
Packit 1470ea
    <include xmlns="http://www.w3.org/2001/XInclude" href="cc-by-sa-3-0.xml"/>
Packit 1470ea
Packit 1470ea
    <desc>Gerindo alocação e desalocação de memória no C</desc>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Rafael Fontenelle</mal:name>
Packit 1470ea
      <mal:email>rafaelff@gnome.org</mal:email>
Packit 1470ea
      <mal:years>2017</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
  <title>Gerenciamento de memória</title>
Packit 1470ea
Packit 1470ea
  

Packit 1470ea
    The GNOME stack is predominantly written in C, so dynamically allocated
Packit 1470ea
    memory has to be managed manually. Through use of GLib convenience APIs,
Packit 1470ea
    memory management can be trivial, but programmers always need to keep memory
Packit 1470ea
    in mind when writing code.
Packit 1470ea
  

Packit 1470ea
Packit 1470ea
  

Packit 1470ea
    It is assumed that the reader is familiar with the idea of heap allocation
Packit 1470ea
    of memory using malloc() and free(), and knows of
Packit 1470ea
    the paired GLib equivalents, g_malloc() and
Packit 1470ea
    g_free().
Packit 1470ea
  

Packit 1470ea
Packit 1470ea
  <synopsis>
Packit 1470ea
    <title>Resumo</title>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      There are three situations to avoid, in order of descending importance:
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    <list type="numbered">
Packit 1470ea
      <item>

Using memory after freeing it (use-after-free).

</item>
Packit 1470ea
      <item>

Using memory before allocating it.

</item>
Packit 1470ea
      <item>

Not freeing memory after allocating it (leaking).

</item>
Packit 1470ea
    </list>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Key principles, in no particular order:
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    <list>
Packit 1470ea
      <item>

Packit 1470ea
        Determine and document whether each variable is owned or unowned. They
Packit 1470ea
        must never change from one to the other at runtime.
Packit 1470ea
        (<link xref="#principles"/>)
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Determine and document the ownership transfers at function boundaries.
Packit 1470ea
        (<link xref="#principles"/>)
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Ensure that each assignment, function call and function return respects
Packit 1470ea
        the relevant ownership transfers. (<link xref="#assignments"/>,
Packit 1470ea
        <link xref="#function-calls"/>, <link xref="#function-returns"/>)
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Use reference counting rather than explicit finalization where possible.
Packit 1470ea
        (<link xref="#reference-counting"/>)
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Use GLib convenience functions like
Packit 1470ea
        <link xref="#g-clear-object">g_clear_object()</link> where
Packit 1470ea
        possible. (<link xref="#convenience-functions"/>)
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Do not split memory management across code paths.
Packit 1470ea
        (<link xref="#principles"/>)
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Use the single-path cleanup pattern for large or complex functions.
Packit 1470ea
        (<link xref="#single-path-cleanup"/>)
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Leaks should be checked for using Valgrind or the address sanitizer.
Packit 1470ea
        (<link xref="#verification"/>)
Packit 1470ea
      

</item>
Packit 1470ea
    </list>
Packit 1470ea
  </synopsis>
Packit 1470ea
Packit 1470ea
  <section id="principles">
Packit 1470ea
    <title>Princípios do gerenciamento de memória</title>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      The normal approach to memory management is for the programmer to keep
Packit 1470ea
      track of which variables point to allocated memory, and to manually free
Packit 1470ea
      them when they are no longer needed. This is correct, but can be clarified
Packit 1470ea
      by introducing the concept of ownership, which is the piece of
Packit 1470ea
      code (such as a function, struct or object) which is responsible for
Packit 1470ea
      freeing a piece of allocated memory (an allocation). Each
Packit 1470ea
      allocation has exactly one owner; this owner may change as the program
Packit 1470ea
      runs, by transferring ownership to another piece of code. Each
Packit 1470ea
      variable is owned or unowned, according to whether the
Packit 1470ea
      scope containing it is always its owner. Each function parameter and
Packit 1470ea
      return type either transfers ownership of the values passed to it, or it
Packit 1470ea
      doesn’t. If code which owns some memory doesn’t deallocate that memory,
Packit 1470ea
      that’s a memory leak. If code which doesn’t own some memory frees it,
Packit 1470ea
      that’s a double-free. Both are bad.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      By statically calculating which variables are owned, memory
Packit 1470ea
      management becomes a simple task of unconditionally freeing the owned
Packit 1470ea
      variables before they leave their scope, and not freeing the
Packit 1470ea
      unowned variables (see <link xref="#single-path-cleanup"/>). The key
Packit 1470ea
      question to answer for all memory is: which code has ownership of this
Packit 1470ea
      memory?
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      There is an important restriction here: variables must
Packit 1470ea
      never change from owned to unowned (or vice-versa)
Packit 1470ea
      at runtime. This restriction is key to simplifying memory management.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Por exemplo, considere as funções:

Packit 1470ea
Packit 1470ea
    gchar *generate_string (const gchar *template);
Packit 1470ea
void print_string (const gchar *str);
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      The following code has been annotated to note where the ownership
Packit 1470ea
      transfers happen:
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    gchar *my_str = NULL;  /* owned */
Packit 1470ea
const gchar *template;  /* unowned */
Packit 1470ea
GValue value = G_VALUE_INIT;  /* owned */
Packit 1470ea
g_value_init (&value, G_TYPE_STRING);
Packit 1470ea
Packit 1470ea
/* Transfers ownership of a string from the function to the variable. */
Packit 1470ea
template = "XXXXXX";
Packit 1470ea
my_str = generate_string (template);
Packit 1470ea
Packit 1470ea
/* No ownership transfer. */
Packit 1470ea
print_string (my_str);
Packit 1470ea
Packit 1470ea
/* Transfer ownership. We no longer have to free @my_str. */
Packit 1470ea
g_value_take_string (&value, my_str);
Packit 1470ea
Packit 1470ea
/* We still have ownership of @value, so free it before it goes out of scope. */
Packit 1470ea
g_value_unset (&value);
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      There are a few points here: Firstly, the ‘owned’ comments by the variable
Packit 1470ea
      declarations denote that those variables are owned by the local scope, and
Packit 1470ea
      hence need to be freed before they go out of scope. The alternative is
Packit 1470ea
      ‘unowned’, which means the local scope does not have ownership,
Packit 1470ea
      and must not free the variables before going out of scope.
Packit 1470ea
      Similarly, ownership must not be transferred to them on
Packit 1470ea
      assignment.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Secondly, the variable type modifiers reflect whether they transfer
Packit 1470ea
      ownership: because my_str is owned by the local scope, it has
Packit 1470ea
      type gchar, whereas template is
Packit 1470ea
      const to denote it is unowned. Similarly, the
Packit 1470ea
      template parameter of generate_string() and the
Packit 1470ea
      str parameter of print_string() are
Packit 1470ea
      const because no ownership is transferred when those
Packit 1470ea
      functions are called. As ownership is transferred for the string
Packit 1470ea
      parameter of g_value_take_string(), we can expect its type to
Packit 1470ea
      be gchar.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      (Note that this is not the case for
Packit 1470ea
      <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html">
Packit 1470ea
      GObject</link>s and subclasses, which can never be
Packit 1470ea
      const. It is only the case for strings and simple
Packit 1470ea
      structs.)
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Finally, a few libraries use a function naming convention to indicate
Packit 1470ea
      ownership transfer, for example using ‘take’ in a function name to
Packit 1470ea
      indicate full transfer of parameters, as with
Packit 1470ea
      g_value_take_string(). Note that different libraries use
Packit 1470ea
      different conventions, as shown below:
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
      
Packit 1470ea
      
Packit 1470ea
      
Packit 1470ea
        
Packit 1470ea
          

Function name

Packit 1470ea
          

Convention 1 (standard)

Packit 1470ea
          

Convention 2 (alternate)

Packit 1470ea
          

Convention 3 (<cmd>gdbus-codegen</cmd>)

Packit 1470ea
        
Packit 1470ea
      
Packit 1470ea
      
Packit 1470ea
        
Packit 1470ea
          

get

Packit 1470ea
          

No transfer

Packit 1470ea
          

Any transfer

Packit 1470ea
          

Full transfer

Packit 1470ea
        
Packit 1470ea
Packit 1470ea
        
Packit 1470ea
          

dup

Packit 1470ea
          

Full transfer

Packit 1470ea
          

Não utilizado

Packit 1470ea
          

Não utilizado

Packit 1470ea
        
Packit 1470ea
Packit 1470ea
        
Packit 1470ea
          

peek

Packit 1470ea
          

Não utilizado

Packit 1470ea
          

Não utilizado

Packit 1470ea
          

No transfer

Packit 1470ea
        
Packit 1470ea
Packit 1470ea
        
Packit 1470ea
          

set

Packit 1470ea
          

No transfer

Packit 1470ea
          

No transfer

Packit 1470ea
          

No transfer

Packit 1470ea
        
Packit 1470ea
Packit 1470ea
        
Packit 1470ea
          

take

Packit 1470ea
          

Full transfer

Packit 1470ea
          

Não utilizado

Packit 1470ea
          

Não utilizado

Packit 1470ea
        
Packit 1470ea
Packit 1470ea
        
Packit 1470ea
          

steal

Packit 1470ea
          

Full transfer

Packit 1470ea
          

Full transfer

Packit 1470ea
          

Full transfer

Packit 1470ea
        
Packit 1470ea
      
Packit 1470ea
    
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Ideally, all functions have a (transfer)
Packit 1470ea
      <link xref="introspection">introspection annotation</link> for all
Packit 1470ea
      relevant parameters and the return value. Failing that, here is a set of
Packit 1470ea
      guidelines to use to determine whether ownership of a return value is
Packit 1470ea
      transferred:
Packit 1470ea
    

Packit 1470ea
    <steps>
Packit 1470ea
      <item>

Packit 1470ea
        If the type has an introspection (transfer) annotation,
Packit 1470ea
        look at that.
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Otherwise, if the type is const, there is no transfer.
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Otherwise, if the function documentation explicitly specifies the return
Packit 1470ea
        value must be freed, there is full or container transfer.
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Otherwise, if the function is named ‘dup’, ‘take’ or ‘steal’, there is
Packit 1470ea
        full or container transfer.
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Otherwise, if the function is named ‘peek’, there is no transfer.
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        Otherwise, you need to look at the function’s code to determine whether
Packit 1470ea
        it intends ownership to be transferred. Then file a bug against the
Packit 1470ea
        documentation for that function, and ask for an introspection annotation
Packit 1470ea
        to be added.
Packit 1470ea
      

</item>
Packit 1470ea
    </steps>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Given this ownership and transfer infrastructure, the correct approach to
Packit 1470ea
      memory allocation can be mechanically determined for each situation. In
Packit 1470ea
      each case, the copy() function must be appropriate to the
Packit 1470ea
      data type, for example g_strdup() for strings, or
Packit 1470ea
      g_object_ref() for GObjects.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      When thinking about ownership transfer,
Packit 1470ea
      malloc()/free() and reference counting are
Packit 1470ea
      equivalent: in the former case, a newly allocated piece of heap memory is
Packit 1470ea
      transferred; in the latter, a newly incremented reference.
Packit 1470ea
      See <link xref="#reference-counting"/>.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    <section id="assignments">
Packit 1470ea
      <title>Assignments</title>
Packit 1470ea
Packit 1470ea
      
Packit 1470ea
        
Packit 1470ea
        
Packit 1470ea
        
Packit 1470ea
          
Packit 1470ea
            

Assignment from/to

Packit 1470ea
            

Owned destination

Packit 1470ea
            

Unowned destination

Packit 1470ea
          
Packit 1470ea
        
Packit 1470ea
        
Packit 1470ea
Packit 1470ea
          
Packit 1470ea
            

Owned source

Packit 1470ea
            
Packit 1470ea
              

Packit 1470ea
                Copy or move the source to the destination.
Packit 1470ea
              

Packit 1470ea
              owned_dest = copy (owned_src)
Packit 1470ea
              owned_dest = owned_src; owned_src = NULL
Packit 1470ea
            
Packit 1470ea
            
Packit 1470ea
              

Packit 1470ea
                Pure assignment, assuming the unowned variable is not used after
Packit 1470ea
                the owned one is freed.
Packit 1470ea
              

Packit 1470ea
              unowned_dest = owned_src
Packit 1470ea
            
Packit 1470ea
          
Packit 1470ea
Packit 1470ea
          
Packit 1470ea
            

Unowned source

Packit 1470ea
            
Packit 1470ea
              

Copy the source to the destination.

Packit 1470ea
              owned_dest = copy (unowned_src)
Packit 1470ea
            
Packit 1470ea
            
Packit 1470ea
              

Pure assignment.

Packit 1470ea
              unowned_dest = unowned_src
Packit 1470ea
            
Packit 1470ea
          
Packit 1470ea
        
Packit 1470ea
      
Packit 1470ea
    </section>
Packit 1470ea
Packit 1470ea
    <section id="function-calls">
Packit 1470ea
      <title>Function Calls</title>
Packit 1470ea
Packit 1470ea
      
Packit 1470ea
        
Packit 1470ea
        
Packit 1470ea
        
Packit 1470ea
          
Packit 1470ea
            

Call from/to

Packit 1470ea
            

Transfer full parameter

Packit 1470ea
            

Transfer none parameter

Packit 1470ea
          
Packit 1470ea
        
Packit 1470ea
        
Packit 1470ea
Packit 1470ea
          
Packit 1470ea
            

Owned source

Packit 1470ea
            
Packit 1470ea
              

Packit 1470ea
                Copy or move the source for the parameter.
Packit 1470ea
              

Packit 1470ea
              function_call (copy (owned_src))
Packit 1470ea
              function_call (owned_src); owned_src = NULL
Packit 1470ea
            
Packit 1470ea
            
Packit 1470ea
              

Packit 1470ea
                Pure parameter passing.
Packit 1470ea
              

Packit 1470ea
              function_call (owned_src)
Packit 1470ea
            
Packit 1470ea
          
Packit 1470ea
Packit 1470ea
          
Packit 1470ea
            

Unowned source

Packit 1470ea
            
Packit 1470ea
              

Copy the source for the parameter.

Packit 1470ea
              function_call (copy (unowned_src))
Packit 1470ea
            
Packit 1470ea
            
Packit 1470ea
              

Pure parameter passing.

Packit 1470ea
              function_call (unowned_src)
Packit 1470ea
            
Packit 1470ea
          
Packit 1470ea
        
Packit 1470ea
      
Packit 1470ea
    </section>
Packit 1470ea
Packit 1470ea
    <section id="function-returns">
Packit 1470ea
      <title>Function Returns</title>
Packit 1470ea
Packit 1470ea
      
Packit 1470ea
        
Packit 1470ea
        
Packit 1470ea
        
Packit 1470ea
          
Packit 1470ea
            

Return from/to

Packit 1470ea
            

Transfer full return

Packit 1470ea
            

Transfer none return

Packit 1470ea
          
Packit 1470ea
        
Packit 1470ea
        
Packit 1470ea
Packit 1470ea
          
Packit 1470ea
            

Owned source

Packit 1470ea
            
Packit 1470ea
              

Packit 1470ea
                Pure variable return.
Packit 1470ea
              

Packit 1470ea
              return owned_src
Packit 1470ea
            
Packit 1470ea
            
Packit 1470ea
              

Packit 1470ea
                Invalid. The source needs to be freed, so the return value would
Packit 1470ea
                use freed memory — a use-after-free error.
Packit 1470ea
              

Packit 1470ea
            
Packit 1470ea
          
Packit 1470ea
Packit 1470ea
          
Packit 1470ea
            

Unowned source

Packit 1470ea
            
Packit 1470ea
              

Copy the source for the return.

Packit 1470ea
              return copy (unowned_src)
Packit 1470ea
            
Packit 1470ea
            
Packit 1470ea
              

Pure variable passing.

Packit 1470ea
              return unowned_src
Packit 1470ea
            
Packit 1470ea
          
Packit 1470ea
        
Packit 1470ea
      
Packit 1470ea
    </section>
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="documentation">
Packit 1470ea
    <title>Documentação</title>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Documenting the ownership transfer for each function parameter and return,
Packit 1470ea
      and the ownership for each variable, is important. While they may be clear
Packit 1470ea
      when writing the code, they are not clear a few months later; and may
Packit 1470ea
      never be clear to users of an API. They should always be documented.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      The best way to document ownership transfer is to use the
Packit 1470ea
      <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations#Memory_and_lifecycle_management">
Packit 1470ea
      (transfer)</link> annotation introduced by
Packit 1470ea
      <link xref="introspection">gobject-introspection</link>. Include this in
Packit 1470ea
      the API documentation comment for each function parameter and return type.
Packit 1470ea
      If a function is not public API, write a documentation comment for it
Packit 1470ea
      anyway and include the (transfer) annotations. By doing so,
Packit 1470ea
      the introspection tools can also read the annotations and use them to
Packit 1470ea
      correctly introspect the API.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Por exemplo:

Packit 1470ea
    /**
Packit 1470ea
 * g_value_take_string:
Packit 1470ea
 * @value: (transfer none): an initialized #GValue
Packit 1470ea
 * @str: (transfer full): string to set it to
Packit 1470ea
 *
Packit 1470ea
 * Function documentation goes here.
Packit 1470ea
 */
Packit 1470ea
Packit 1470ea
/**
Packit 1470ea
 * generate_string:
Packit 1470ea
 * @template: (transfer none): a template to follow when generating the string
Packit 1470ea
 *
Packit 1470ea
 * Function documentation goes here.
Packit 1470ea
 *
Packit 1470ea
 * Returns: (transfer full): a newly generated string
Packit 1470ea
 */
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Ownership for variables can be documented using inline comments. These are
Packit 1470ea
      non-standard, and not read by any tools, but can form a convention if used
Packit 1470ea
      consistently.
Packit 1470ea
    

Packit 1470ea
    GObject *some_owned_object = NULL;  /* owned */
Packit 1470ea
GObject *some_unowned_object;  /* unowned */
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      The documentation for <link xref="#container-types"/> is similarly only a
Packit 1470ea
      convention; it includes the type of the contained elements too:
Packit 1470ea
    

Packit 1470ea
    GPtrArray/*<owned gchar*>*/ *some_unowned_string_array;  /* unowned */
Packit 1470ea
GPtrArray/*<owned gchar*>*/ *some_owned_string_array = NULL;  /* owned */
Packit 1470ea
GPtrArray/*<unowned GObject*>*/ *some_owned_object_array = NULL;  /* owned */
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Note also that owned variables should always be initialized so that
Packit 1470ea
      freeing them is more convenient. See
Packit 1470ea
      <link xref="#convenience-functions"/>.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Also note that some types, for example basic C types like strings, can
Packit 1470ea
      have the const modifier added if they are unowned, to take
Packit 1470ea
      advantage of compiler warnings resulting from assigning those variables to
Packit 1470ea
      owned variables (which must not use the const
Packit 1470ea
      modifier). If so, the /* unowned */ comment may be omitted.
Packit 1470ea
    

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="reference-counting">
Packit 1470ea
    <title>Contagem de referência</title>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      As well as conventional malloc()/free()-style
Packit 1470ea
      types, GLib has various reference counted types —
Packit 1470ea
      <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html">
Packit 1470ea
      GObject</link> being a prime example.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      The concepts of ownership and transfer apply just as well to reference
Packit 1470ea
      counted types as they do to allocated types. A scope owns a
Packit 1470ea
      reference counted type if it holds a strong reference to the instance
Packit 1470ea
      (for example by calling
Packit 1470ea
      <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref">
Packit 1470ea
      g_object_ref()</link>). An instance can be ‘copied’ by
Packit 1470ea
      calling g_object_ref() again. Ownership can be freed with
Packit 1470ea
      <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-unref">
Packit 1470ea
      g_object_unref()</link> — even though this may not actually
Packit 1470ea
      finalize the instance, it frees the current scope’s ownership of that
Packit 1470ea
      instance.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      See <link xref="#g-clear-object"/> for a convenient way of handling
Packit 1470ea
      GObject references.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      There are other reference counted types in GLib, such as
Packit 1470ea
      <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html">
Packit 1470ea
      GHashTable</link> (using
Packit 1470ea
      <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-ref">
Packit 1470ea
      g_hash_table_ref()</link> and
Packit 1470ea
      <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-unref">
Packit 1470ea
      g_hash_table_unref()</link>), or
Packit 1470ea
      <link href="https://developer.gnome.org/glib/stable/glib-GVariant.html">
Packit 1470ea
      GVariant</link>
Packit 1470ea
      (<link href="https://developer.gnome.org/glib/stable/glib-GVariant.html#g-variant-ref">
Packit 1470ea
      g_variant_ref()</link>,
Packit 1470ea
      <link href="https://developer.gnome.org/glib/stable/glib-GVariant.html#g-variant-unref">
Packit 1470ea
      g_variant_unref()</link>). Some types, like
Packit 1470ea
      GHashTable, support both reference counting and explicit
Packit 1470ea
      finalization. Reference counting should always be used in preference,
Packit 1470ea
      because it allows instances to be easily shared between multiple scopes
Packit 1470ea
      (each holding their own reference) without having to allocate multiple
Packit 1470ea
      copies of the instance. This saves memory.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    <section id="floating-references">
Packit 1470ea
      <title>Floating References</title>
Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        Classes which are derived from
Packit 1470ea
        <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#GInitiallyUnowned">GInitiallyUnowned</link>,
Packit 1470ea
        as opposed to
Packit 1470ea
        <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#GObject-struct">GObject</link>
Packit 1470ea
        have an initial reference which is floating, meaning that no
Packit 1470ea
        code owns the reference. As soon as
Packit 1470ea
        <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref-sink">g_object_ref_sink()</link>
Packit 1470ea
        is called on the object, the floating reference is converted to a strong
Packit 1470ea
        reference, and the calling code assumes ownership of the object.
Packit 1470ea
      

Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        Floating references are a convenience for use in C in APIs, such as
Packit 1470ea
        GTK+, where large numbers of objects must be created and organized into
Packit 1470ea
        a hierarchy. In these cases, calling g_object_unref() to
Packit 1470ea
        drop all the strong references would result in a lot of code.
Packit 1470ea
      

Packit 1470ea
Packit 1470ea
      <example>
Packit 1470ea
        

Packit 1470ea
          Floating references allow the following code to be simplified:
Packit 1470ea
        

Packit 1470ea
        GtkWidget *new_widget;
Packit 1470ea
Packit 1470ea
new_widget = gtk_some_widget_new ();
Packit 1470ea
gtk_container_add (some_container, new_widget);
Packit 1470ea
g_object_unref (new_widget);
Packit 1470ea
Packit 1470ea
        

Packit 1470ea
          Instead, the following code can be used, with the
Packit 1470ea
          GtkContainer assuming ownership of the floating
Packit 1470ea
          reference:
Packit 1470ea
        

Packit 1470ea
        
Packit 1470ea
gtk_container_add (some_container, gtk_some_widget_new ());
Packit 1470ea
      </example>
Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        Floating references are only used by a few APIs — in particular,
Packit 1470ea
        GtkWidget and all its subclasses. You must learn which APIs
Packit 1470ea
        support it, and which APIs consume floating references, and only use
Packit 1470ea
        them together.
Packit 1470ea
      

Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        Note that g_object_ref_sink() is equivalent to
Packit 1470ea
        g_object_ref() when called on a non-floating reference,
Packit 1470ea
        making gtk_container_add() no different from any other
Packit 1470ea
        function in such cases.
Packit 1470ea
      

Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        See the <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#floating-ref">GObject
Packit 1470ea
        manual</link> for more information on floating references.
Packit 1470ea
      

Packit 1470ea
    </section>
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="convenience-functions">
Packit 1470ea
    <title>Convenience Functions</title>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      GLib provides various convenience functions for memory management,
Packit 1470ea
      especially for GObjects. Three will be covered here, but others exist —
Packit 1470ea
      check the GLib API documentation for more. They typically follow similar
Packit 1470ea
      naming schemas to these three (using ‘_full’ suffixes, or the verb ‘clear’
Packit 1470ea
      in the function name).
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    <section id="g-clear-object">
Packit 1470ea
      <title>g_clear_object()</title>
Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-clear-object">
Packit 1470ea
        g_clear_object()</link> is a version of
Packit 1470ea
        <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-unref">
Packit 1470ea
        g_object_unref()</link> which unrefs a GObject and then
Packit 1470ea
        clears the pointer to it to NULL.
Packit 1470ea
      

Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        This makes it easier to implement code that guarantees a GObject pointer
Packit 1470ea
        is always either NULL, or has ownership of a GObject (but
Packit 1470ea
        which never points to a GObject it no longer owns).
Packit 1470ea
      

Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        By initialising all owned GObject pointers to NULL, freeing
Packit 1470ea
        them at the end of the scope is as simple as calling
Packit 1470ea
        g_clear_object() without any checks, as discussed in
Packit 1470ea
        <link xref="#single-path-cleanup"/>:
Packit 1470ea
      

Packit 1470ea
      void
Packit 1470ea
my_function (void)
Packit 1470ea
{
Packit 1470ea
  GObject *some_object = NULL;  /* owned */
Packit 1470ea
Packit 1470ea
  if (rand ())
Packit 1470ea
    {
Packit 1470ea
      some_object = create_new_object ();
Packit 1470ea
      /* do something with the object */
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
  g_clear_object (&some_object);
Packit 1470ea
}
Packit 1470ea
    </section>
Packit 1470ea
Packit 1470ea
    <section id="g-list-free-full">
Packit 1470ea
      <title>g_list_free_full()</title>
Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        <link href="https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html#g-list-free-full">
Packit 1470ea
        g_list_free_full()</link> frees all the elements in a
Packit 1470ea
        linked list, and all their data. It is much more convenient
Packit 1470ea
        than iterating through the list to free all the elements’ data, then
Packit 1470ea
        calling <link href="https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html#g-list-free">
Packit 1470ea
        g_list_free()</link> to free the GList
Packit 1470ea
        elements themselves.
Packit 1470ea
      

Packit 1470ea
    </section>
Packit 1470ea
Packit 1470ea
    <section id="g-hash-table-new-full">
Packit 1470ea
      <title>g_hash_table_new_full()</title>
Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-new-full">
Packit 1470ea
        g_hash_table_new_full()</link> is a newer version of
Packit 1470ea
        <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-new">
Packit 1470ea
        g_hash_table_new()</link> which allows setting functions to
Packit 1470ea
        destroy each key and value in the hash table when they are removed.
Packit 1470ea
        These functions are then automatically called for all keys and values
Packit 1470ea
        when the hash table is destroyed, or when an entry is removed using
Packit 1470ea
        g_hash_table_remove().
Packit 1470ea
      

Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        Essentially, it simplifies memory management of keys and values to the
Packit 1470ea
        question of whether they are present in the hash table. See
Packit 1470ea
        <link xref="#container-types"/> for a discussion on ownership of
Packit 1470ea
        elements within container types.
Packit 1470ea
      

Packit 1470ea
Packit 1470ea
      

Packit 1470ea
        A similar function exists for GPtrArray:
Packit 1470ea
        <link href="https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html#g-ptr-array-new-with-free-func">
Packit 1470ea
        g_ptr_array_new_with_free_func()</link>.
Packit 1470ea
      

Packit 1470ea
    </section>
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="container-types">
Packit 1470ea
    <title>Container Types</title>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      When using container types, such as GPtrArray or
Packit 1470ea
      GList, an additional level of ownership is introduced: as
Packit 1470ea
      well as the ownership of the container instance, each element in the
Packit 1470ea
      container is either owned or unowned too. By nesting containers, multiple
Packit 1470ea
      levels of ownership must be tracked. Ownership of owned elements belongs
Packit 1470ea
      to the container; ownership of the container belongs to the scope it’s in
Packit 1470ea
      (which may be another container).
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      A key principle for simplifying this is to ensure that all elements in a
Packit 1470ea
      container have the same ownership: they are either all owned, or all
Packit 1470ea
      unowned. This happens automatically if the normal
Packit 1470ea
      <link xref="#convenience-functions"/> are used for types like
Packit 1470ea
      GPtrArray and GHashTable.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      If elements in a container are owned, adding them to the
Packit 1470ea
      container is essentially an ownership transfer. For example, for an array
Packit 1470ea
      of strings, if the elements are owned, the definition of
Packit 1470ea
      g_ptr_array_add() is effectively:
Packit 1470ea
    

Packit 1470ea
    /**
Packit 1470ea
 * g_ptr_array_add:
Packit 1470ea
 * @array: a #GPtrArray
Packit 1470ea
 * @str: (transfer full): string to add
Packit 1470ea
 */
Packit 1470ea
void
Packit 1470ea
g_ptr_array_add (GPtrArray *array,
Packit 1470ea
                 gchar     *str);
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      So, for example, constant (unowned) strings must be added to the array
Packit 1470ea
      using g_ptr_array_add (array, g_strdup ("constant string")).
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Whereas if the elements are unowned, the definition is effectively:
Packit 1470ea
    

Packit 1470ea
    /**
Packit 1470ea
 * g_ptr_array_add:
Packit 1470ea
 * @array: a #GPtrArray
Packit 1470ea
 * @str: (transfer none): string to add
Packit 1470ea
 */
Packit 1470ea
void
Packit 1470ea
g_ptr_array_add (GPtrArray   *array,
Packit 1470ea
                 const gchar *str);
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Here, constant strings can be added without copying them:
Packit 1470ea
      g_ptr_array_add (array, "constant string").
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      See <link xref="#documentation"/> for examples of comments to add to
Packit 1470ea
      variable definitions to annotate them with the element type and ownership.
Packit 1470ea
    

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="single-path-cleanup">
Packit 1470ea
    <title>Single-Path Cleanup</title>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      A useful design pattern for more complex functions is to have a single
Packit 1470ea
      control path which cleans up (frees) allocations and returns to the
Packit 1470ea
      caller. This vastly simplifies tracking of allocations, as it’s no longer
Packit 1470ea
      necessary to mentally work out which allocations have been freed on each
Packit 1470ea
      code path — all code paths end at the same point, so perform all the frees
Packit 1470ea
      then. The benefits of this approach rapidly become greater for larger
Packit 1470ea
      functions with more owned local variables; it may not make sense to apply
Packit 1470ea
      the pattern to smaller functions.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      This approach has two requirements:
Packit 1470ea
    

Packit 1470ea
    <list type="numbered">
Packit 1470ea
      <item>

Packit 1470ea
        The function returns from a single point, and uses goto to
Packit 1470ea
        reach that point from other paths.
Packit 1470ea
      

</item>
Packit 1470ea
      <item>

Packit 1470ea
        All owned variables are set to NULL when initialized or
Packit 1470ea
        when ownership is transferred away from them.
Packit 1470ea
      

</item>
Packit 1470ea
    </list>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      The example below is for a small function (for brevity), but should
Packit 1470ea
      illustrate the principles for application of the pattern to larger
Packit 1470ea
      functions:
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    <listing>
Packit 1470ea
      <title>Single-Path Cleanup Example</title>
Packit 1470ea
      <desc>
Packit 1470ea
        Example of implementing single-path cleanup for a simple function
Packit 1470ea
      </desc>
Packit 1470ea
      GObject *
Packit 1470ea
some_function (GError **error)
Packit 1470ea
{
Packit 1470ea
  gchar *some_str = NULL;  /* owned */
Packit 1470ea
  GObject *temp_object = NULL;  /* owned */
Packit 1470ea
  const gchar *temp_str;
Packit 1470ea
  GObject *my_object = NULL;  /* owned */
Packit 1470ea
  GError *child_error = NULL;  /* owned */
Packit 1470ea
Packit 1470ea
  temp_object = generate_object ();
Packit 1470ea
  temp_str = "example string";
Packit 1470ea
Packit 1470ea
  if (rand ())
Packit 1470ea
    {
Packit 1470ea
      some_str = g_strconcat (temp_str, temp_str, NULL);
Packit 1470ea
    }
Packit 1470ea
  else
Packit 1470ea
    {
Packit 1470ea
      some_operation_which_might_fail (&child_error);
Packit 1470ea
Packit 1470ea
      if (child_error != NULL)
Packit 1470ea
        {
Packit 1470ea
          goto done;
Packit 1470ea
        }
Packit 1470ea
Packit 1470ea
      my_object = generate_wrapped_object (temp_object);
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
done:
Packit 1470ea
  /* Here, @some_str is either NULL or a string to be freed, so can be passed to
Packit 1470ea
   * g_free() unconditionally.
Packit 1470ea
   *
Packit 1470ea
   * Similarly, @temp_object is either NULL or an object to be unreffed, so can
Packit 1470ea
   * be passed to g_clear_object() unconditionally. */
Packit 1470ea
  g_free (some_str);
Packit 1470ea
  g_clear_object (&temp_object);
Packit 1470ea
Packit 1470ea
  /* The pattern can also be used to ensure that the function always returns
Packit 1470ea
   * either an error or a return value (but never both). */
Packit 1470ea
  if (child_error != NULL)
Packit 1470ea
    {
Packit 1470ea
      g_propagate_error (error, child_error);
Packit 1470ea
      g_clear_object (&my_object);
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
  return my_object;
Packit 1470ea
}
Packit 1470ea
    </listing>
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="verification">
Packit 1470ea
    <title>Verification</title>
Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Memory leaks can be checked for in two ways: static analysis, and runtime
Packit 1470ea
      leak checking.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Static analysis with tools like
Packit 1470ea
      <link xref="tooling#coverity">Coverity</link>, the
Packit 1470ea
      <link xref="tooling#clang-static-analyzer">Clang static analyzer</link> or
Packit 1470ea
      <link xref="tooling#tartan">Tartan</link> can
Packit 1470ea
      catch some leaks, but require knowledge of the ownership transfer of every
Packit 1470ea
      function called in the code. Domain-specific static analyzers like Tartan
Packit 1470ea
      (which knows about GLib memory allocation and transfer) can perform better
Packit 1470ea
      here, but Tartan is quite a young project and still misses things (a low
Packit 1470ea
      true positive rate). It is recommended that code be put through a static
Packit 1470ea
      analyzer, but the primary tool for detecting leaks should be runtime leak
Packit 1470ea
      checking.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      Runtime leak checking is done using
Packit 1470ea
      <link xref="tooling#valgrind">Valgrind</link>, using its
Packit 1470ea
      <link xref="tooling#memcheck">memcheck</link> tool. Any leak it detects as
Packit 1470ea
      ‘definitely losing memory’ should be fixed. Many of the leaks which
Packit 1470ea
      ‘potentially’ lose memory are not real leaks, and should be added to the
Packit 1470ea
      suppression file.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      If compiling with a recent version of Clang or GCC, the
Packit 1470ea
      <link xref="tooling#address-sanitizer">address sanitizer</link> can be
Packit 1470ea
      enabled instead, and it will detect memory leaks and overflow problems at
Packit 1470ea
      runtime, but without the difficulty of running Valgrind in the right
Packit 1470ea
      environment. Note, however, that it is still a young tool, so may fail in
Packit 1470ea
      some cases.
Packit 1470ea
    

Packit 1470ea
Packit 1470ea
    

Packit 1470ea
      See <link xref="tooling#valgrind"/> for more information on using
Packit 1470ea
      Valgrind.
Packit 1470ea
    

Packit 1470ea
  </section>
Packit 1470ea
</page>