C linked list implementation For the following C linked list implementation, please give me some suggestions for improved efficiency, style and design. This implementation is not 100% complete, please give some suggestions for additional features. Notice the data type for the list is void*, I want it to be as generic as possible.

accList.h:

#ifndef ACCLIST_H
#define ACCLIST_H

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

struct accListNode                 //the nodes of a linked-list for any data type
{
  void *data;                     //generic pointer to any data type
  struct accListNode *next;       //the next node in the list
};

struct accList                    //a linked-list consisting of accListNodes
{
  struct accListNode *head;
  struct accListNode *tail;
  int size;
};

void accList_allocate(struct accList *theList);           //allocate the accList and set to NULL
void appendToEnd(void *data, struct accList *theList);    //append data to the end of the accList
void removeData(void *data, struct accList *theList);         //removes data from accList

#endif


accList.c:

#include "accList.h"
#include "cmpsc311.h"

void accList_allocate(struct accList *theList)    //allocate and initialize to NULL values
{
   theList = Malloc(sizeof(struct accList));
   theList-&gt;head = NULL;
   theList-&gt;tail = NULL;
   theList-&gt;size = 0;
}

void appendToEnd(void *data, struct accList *theList)
{
  struct accListNode *newNode = Malloc(sizeof(struct accListNode));
  newNode-&gt;data = data;
  newNode-&gt;next = NULL;
  if(theList-&gt;head == NULL)    //the list is empty
  {
    theList-&gt;head = theList-&gt;tail = newNode;
  }
  else                        //the list is not empty
  {
    theList-&gt;tail-&gt;next = newNode;
    theList-&gt;tail = newNode;
  }
}

void removeData(void *data, struct accList *theList)
{
  if(theList-&gt;head == NULL)                                 //the list is empty
    return;
  else if(theList-&gt;head == theList-&gt;tail)                   //there is one element in the list
  {
    free(theList-&gt;head);
    theList-&gt;head = NULL;
  }
  else if(data == theList-&gt;head-&gt;data)                     //the element to be removed is the head
  {
    struct accListNode *temp = theList-&gt;head-&gt;next;
    free(theList-&gt;head);
    theList-&gt;head = temp;
  }
  else if(data == theList-&gt;tail-&gt;data)                     //the element to be removed is the tail
  {
    struct accListNode *cur;
    struct accListNode *prev = NULL;
    for(cur = theList-&gt;head; cur-&gt;next != NULL; prev = cur, cur = cur-&gt;next);
    free(theList-&gt;tail);
    prev-&gt;next = NULL;
    theList-&gt;tail = prev;
  }
  else                                                     //any other node
  {
    struct accListNode *prev = NULL;
    struct accListNode *cur;
    for(cur = theList-&gt;head; cur != NULL; prev = cur, cur = cur-&gt;next)
    {
      if(cur-&gt;data == data)   //this is the node we must free
      {
        prev-&gt;next = cur-&gt;next;
        free(cur);
      }
    }
  }
}


I think the remove function needs the most work. I did post that function on this site, however I think I needed to include the whole implementation to get the best feedback. Will this work on an embedded system?
Several problems I see:

accList_allocate

accList_allocate doesn't do what you probably think. It creates a new accList, yes, but this new one will not be visible to the caller (and thus, will be lost as memory leakage). If you want to initialize the pointer passed to it, use a pointer-to-pointer:

void accList_allocate(struct accList **outList)    //allocate and initialize to NULL values
{
   struct accList* theList = Malloc(sizeof(struct accList));
   theList-&gt;head = NULL;
   theList-&gt;tail = NULL;
   theList-&gt;size = 0;
   *outList = theList;
}


Also, you should really check the return value of Malloc. Especially on embedded systems, there's a real possibility of running out of memory. Let the caller handle the error, but tell him that something's wrong.

appendToEnd

Same as with accList_allocate, check Malloc's return value and return some kind of error code if it's NULL. What you're writing there is library code that should always handle errors gracefully and let the caller decide whether to crash and burn or recover and try again.

removeData

Please refer to my answer in your other thread.