Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Need to put several structs into a linked-list

Posted on 2004-08-17
3
Medium Priority
?
201 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
3 Comments
 
LVL 11

Accepted Solution

by:
avizit earned 400 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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
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.

609 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