Solved

Need to put several structs into a linked-list

Posted on 2004-08-17
3
197 Views
Last Modified: 2010-04-20
Hi,

I have a linked-list, and a struct. I have to add several variables (of this struct) to the linked-list. The problem is that I don't know how many structs I will have to create. Any suggestions?
0
Comment
Question by:slavikn
3 Comments
 
LVL 11

Accepted Solution

by:
avizit earned 100 total points
ID: 11822997
you create ( i.e malloc ) teh space required by a struct and then add it to the list

do ithe same as and when you need to add a new struct to the linked list

and when you have to remove any from the list don't forget to free it.


also read this  http://vergil.chemistry.gatech.edu/resources/programming/c-tutorial/lists.html
0
 

Expert Comment

by:BenSaw
ID: 11824049
Here's a .c source file w/ 2 functions - don't worry about the internals
===================================================================
#include <string.h>
#include <malloc.h>

#include "LinkedLists.h"

typedef unsigned long   MEM_ADDR;
typedef unsigned long * PTR;

int _insert_struct_into_doubly_linked_list(
                                                void      **ppBase,
                                                void      *pNew,
                                                unsigned int offsetPrevPtr,
                                                unsigned int offsetNextPtr)
{
      MEM_ADDR *p,
                   *pt;

      //the pointer to be inserted might be the first,
      if ( *(MEM_ADDR**)ppBase == NULL )
      {
            *(MEM_ADDR**)ppBase = (MEM_ADDR*)pNew;
            *(MEM_ADDR**)((char*)pNew + offsetPrevPtr) = NULL;
            *(MEM_ADDR**)((char*)pNew + offsetNextPtr) = NULL;
      }
      else
      {
            //find the last entry
            p = *(MEM_ADDR**)ppBase;

            while ( (pt = *(MEM_ADDR**)((char*)p + offsetNextPtr)) != NULL )
                  p = pt;

            //change the NEXT of the previous last
            *(MEM_ADDR**)((char*)p + offsetNextPtr) = (MEM_ADDR*)pNew;

            //initialize the PREV & NEXT of new last
            *(MEM_ADDR**)((char*)pNew + offsetPrevPtr) = p;
            *(MEM_ADDR**)((char*)pNew + offsetNextPtr) = NULL;
      }
      
      return 0;
}


int _remove_struct_from_doubly_linked_list(
                                                void      **ppBase,
                                                void      *pOld,
                                                size_t      offsetPrevPtr,
                                                size_t      offsetNextPtr)
{
      MEM_ADDR *p,
                   *pt;

      if (! ppBase)
            return -1;
      if (! *(MEM_ADDR**)ppBase)
            return -2;

      //---------------------------------------------------------------------
      // The pointer to be removed might be the first one,... In this case,
      // it may be the ONLY one, but the value of NEXT can always be placed
      // into the pBase, because this is either valid or NULL, which is valid.

      if ( *(MEM_ADDR**)ppBase == (MEM_ADDR*)pOld )
      {
            p = *(MEM_ADDR**)ppBase;
            *(MEM_ADDR**)ppBase = *(MEM_ADDR**)((char*)p + offsetNextPtr);
      }
      else      //element is not first, search for it
      {
            //find the pOld entry
            p = *(MEM_ADDR**)ppBase;

            pt = *(MEM_ADDR**)((char*)p + offsetNextPtr); //use a temp
            while (pt != pOld && pt != NULL)
            {
                  p = pt;
                  pt = *(MEM_ADDR**)((char*)p + offsetNextPtr);
            }

            //check for not found
            if ( *(MEM_ADDR**)((char*)p + offsetNextPtr) == NULL )
                  return -3;

            //change the NEXT of the pevious
            *(MEM_ADDR**)((char*)p + offsetNextPtr) = (*(MEM_ADDR**)((char*)pOld + offsetNextPtr));

            //change the PREVIOUS of the old next, if it exists
            if (*(MEM_ADDR**)((char*)p + offsetNextPtr))
            {
                  p = *(MEM_ADDR**)((char*)pOld + offsetNextPtr);
                  *(MEM_ADDR**)((char*)p + offsetPrevPtr) = *(MEM_ADDR**)((char*)pOld + offsetPrevPtr);
            }
      }

      return 0;
}

Here's the relevant portion of the .h file, (LinkedLists.h)==================================================================
#ifndef __LINKEDLISTS_H
#define __LINKEDLISTS_H

int _insert_struct_into_doubly_linked_list(
            void      **pBase,
            void      *pNew,
            unsigned int offsetPrevPtr,
            unsigned int offsetNextPtr
      );

int _remove_struct_from_doubly_linked_list(
            void      **pBase,
            void      *pOld,
            size_t      offsetPrevPtr,
            size_t      offsetNextPtr
      );

#endif      //ndef __LINKEDLISTS_H

here's a sample call:

      result = _insert_struct_into_doubly_linked_list(
                              (void**)&SessionTableHeadPtr,
                              (void*)p,
                              offsetof(SESSION, pPrevSession),
                              offsetof(SESSION, pNextSession)
                        );
Here, SessionTableHeadPtr is defined as:
static SESSION * SessionTableHeadPtr = NULL;

where SESSION is defined as:

struct _SESSION {
               your struct members here
                .
                .
                .
      struct  _SESSION *pPrevSession;
      struct  _SESSION *pNextSession;
                .
                .
                .
                .
      };

typedef struct _SESSION SESSION;

p is a pointer to the stucture to be inserted.

Hope this helps - Ben
0
 
LVL 1

Author Comment

by:slavikn
ID: 11829066
That was exactly what I did... Just had some other bugs... Thanks anyway.
0

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question