Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are a few approaches you can take, one of which involves storing a <code>void*</code> in your ADT.</p> <p>I've always found this to be a bit of a pain in a linked list since you have to manage it's allocation separately to the list itself. In other words, to allocate a node, you need to alocate both the node and its payload separately (and remember to clean them both up on deletion as well).</p> <p>One approach I've used in the past is to have a 'variable sized' structure like:</p> <pre><code>typedef struct _tNode { struct _tNode *prev; struct _tNode *next; char payload[1]; } tNode; </code></pre> <p>Now that doesn't <em>look</em> variable sized but let's allocate a structure thus:</p> <pre><code>typedef struct { char Name[30]; char Addr[50]; char Phone[20]; } tPerson; tNode *node = malloc (sizeof (tNode) - 1 + sizeof (tPerson)); </code></pre> <p>Now you have a node that, for all intents and purposes, looks like this:</p> <pre><code>typedef struct _tNode { struct _tNode *prev; struct _tNode *next; char Name[30]; char Addr[50]; char Phone[20]; } tNode; </code></pre> <p>or, in graphical form (where <code>[n]</code> means <code>n</code> bytes):</p> <pre><code>+------------+ | prev[4] | +------------+ | next[4] | +------------+ +-----------+ | payload[1] | | Name[30] | &lt;- overlap +------------+ +-----------+ | Addr[50] | +-----------+ | Phone[20] | +-----------+ </code></pre> <p>That is, assuming you know how to address the payload correctly. This can be done as follows:</p> <pre><code>node-&gt;prev = NULL; node-&gt;next = NULL; tPerson *person = &amp;(node-&gt;payload); // cast for easy changes to payload. strcpy (person-&gt;Name, "Richard Cranium"); strcpy (person-&gt;Addr, "10 Smith St"); strcpy (person-&gt;Phone, "555-5555"); </code></pre> <p>That cast line simply casts the address of the <code>payload</code> character (in the <code>tNode</code> type) to be an address of the actual <code>tPerson</code> payload type.</p> <p>Using this method, you can carry any payload type you want in a node, even <em>different payload types in each node</em>, if you make the structure more like:</p> <pre><code>typedef struct _tNode { struct _tNode *prev; struct _tNode *next; int payloadType; // Allows different payload type at each node. char payload[1]; } tNode; </code></pre> <p>and use <code>payloadType</code> to store an indicator as to what the payload actually is.</p> <p>This has the advantage over a union in that it doesn't waste space, as can be seen with the following:</p> <pre><code>union { int fourBytes; char oneHundredBytes[100]; } u; </code></pre> <p>where 96 bytes are wasted every time you store an integer type in the list (for a 4-byte integer).</p> <p>The payload type in the <code>tNode</code> allows you to easily detect what type of payload this node is carrying, so your code can decide how to process it. You can use something along the lines of:</p> <pre><code>#define PAYLOAD_UNKNOWN 0 #define PAYLOAD_MANAGER 1 #define PAYLOAD_EMPLOYEE 2 #define PAYLOAD_CONTRACTOR 3 </code></pre> <p>or (probably better):</p> <pre><code>typedef enum { PAYLOAD_UNKNOWN, PAYLOAD_MANAGER, PAYLOAD_EMPLOYEE, PAYLOAD_CONTRACTOR } tPayLoad; </code></pre> <p>The only thing you need to watch out for is to ensure that the alignment of the payload is correct. Since both my payload placeholder and the payload are all <code>char</code> types, that's not an issue. However, if your payload consists of types with more stringent alignment requirements (such as something more strict than the pointers, you may need to adjust for it).</p> <p>While I've never seen an environment with alignments more strict than pointers, it <em>is</em> possible according to the ISO C standard.</p> <p>You can usually get the required alignment simply by using a data type for the payload placeholder which has the strictest alignment requirement such as:</p> <pre><code>long payload; </code></pre> <hr> <p>In retrospect, it occurs to me that you probably don't <em>need</em> an array as the payload placeholder. It's simple enough to just have something you can take the address of. I suspect that particular idiom of mine hearkens back to the days where I just stored an array of characters (rather than a structure) and referenced them directly. In that case, you could use <code>payload[]</code> on its own without casting to another type.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload