Results 1 to 15 of 15

Thread: Link List - using array

Hybrid View

  1. #1

    Thread Starter
    New Member
    Join Date
    Oct 2002
    Posts
    10

    Link List - using array

    Hi there
    I got stuck, any help please:

    I created a function which pass a value to struct in a header structure file, however wrong value returned when I inspect it by other functions, the is code as following:

    int ListInit(List* sList, Key key1)
    {

    sList->count = 0;
    sList = NULL;

    sList->ckey = key1; /* I need this to by stored in the header file which is below*/
    return SUCCESS;
    }

    Header file
    ____________________________

    typedef struct CarList
    {

    unsigned ckey; /*in this variable sould be stored then retrieved by the below function*/

    } List;


    int ListInsert(List *sList){
    unsigned key = sList->ckey /* it returns wrong values*/
    switch(key){
    case 0:{
    MakeCompare(sList->temp, sList break;
    }
    }
    }
    teach yourself as you can, when you get stuck ask and do not shy

  2. #2
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    sList = NULL;

    sList->ckey = key1

    By no means this can ever work.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  3. #3

    Thread Starter
    New Member
    Join Date
    Oct 2002
    Posts
    10

    Unhappy

    How?

    sList = NULL \ make the list empty, by List pointer|

    so, could you please tell me how to make the list empty, and how to store the key in the header structure file.

    I got stuck and I cant move on without these intialization?

    thanks in advanced
    teach yourself as you can, when you get stuck ask and do not shy

  4. #4
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    sList = NULL; // set the poiner to NULL
    This actually doesn't change anything of the list itself, only the pointer that previously pointed to it now points to nothing.

    sList->ckey = key1 // dereference
    Since sList is NULL at this point this will invariably create an access violation.

    I need the exact declaration of the structure if I am to help you.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  5. #5

    Thread Starter
    New Member
    Join Date
    Oct 2002
    Posts
    10
    Hi there, this is the structure for both header file and c file:

    list-array.h
    __________

    typedef enum key { MAKE, MODEL, YEAR, REG } Key;

    typedef struct CarInfo
    {
    char *make;
    char *model;
    int year;
    char reg[MAX_REG];

    } Car;

    typedef struct CarList
    {
    unsigned count;
    unsigned ckey;

    Car *Cars[MAXCARS];

    Car *temp;
    void (*FuncComp[NUMCOP])(int);
    } List;

    #define SUCCESS 1
    #define FAILURE 0

    int ListInit(List*, Key, int(*MakeCompare) (Car*, Car*),
    int(*ModelCompare) (Car*, Car*),
    int(*YearCompare) (Car*, Car*),
    int(*RegCompare) (Car*, Car*));


    list-array.c
    _________
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include "list-array.h"

    Car *temp;
    int ListInit(List *sList, Key key1, int(*MakeCompare)(Car *, Car *), int(*ModelCompare)(Car *, Car *),
    int(*YearCompare)(Car *, Car *), int(*RegCompare)(Car *, Car *))
    {

    sList->count = 0;
    sList = NULL;

    sList->ckey = key1;

    sList->FuncComp[0] = *(int*)MakeCompare;
    sList->FuncComp[1] = *(int*)ModelCompare;
    sList->FuncComp[2] = *(int*)YearCompare;
    sList->FuncComp[3] = *(int*)RegCompare;
    return SUCCESS;

    }

    and the following is the description of what to do with ListInit function:
    int ListInit(List*, Key, int(*MakeCompare) (Car*, Car*),
    * int(*ModelCompare) (Car*, Car*),
    * int(*YearCompare) (Car*, Car*),
    * int(*RegCompare) (Car*, Car*));

    * - this function *must* be used to initialise a List
    * object before any other interface routine can be
    * safely applied to the List
    * - accepts a pointer to an existing List variable, and
    * initialises it to represent a "new empty list"
    * - the user must specify what field is to be used for the ordering
    * - the next 4 parameters are the function pointers to compare 2 car
    * structures for each of the Keys. You will need to keep this somewhere
    * in your structure so you can call the appropriate function when needed.
    * The functions must return -1 if the first is less than the second, 0 if
    * they are equal and 1 otherwise. You must write 4 separate functions
    * to be passed in for the 4 different field orderings.
    * - this function returns true if successful, and false
    * if initialisation was unsuccessful

    _____________________
    if any help please;
    thanks in advaned
    teach yourself as you can, when you get stuck ask and do not shy

  6. #6
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Terrible. I hate function pointers used in this way.

    Code:
    list-array.h
    __________
    
    typedef enum key { MAKE, MODEL, YEAR, REG } Key;
    
    typedef struct CarInfo
    {
    char *make;
    char *model;
    int year;
    char reg[MAX_REG];
    
    } Car;
    
    typedef struct CarList
    {
    unsigned count;
    unsigned ckey;
    
    Car *Cars[MAXCARS];
    
    Car *temp;
    COMPARE_FUNC MakeCompare;
    COMPARE_FUNC ModelCompare;
    COMPARE_FUNC YearCompare;
    COMPARE_FUNC RegCompare;
    } List;
    
    #define SUCCESS 1
    #define FAILURE 0
    
    typedef int (*COMPARE_FUNC)(Car*,Car*);
    
    int ListInit(List*, Key, COMPARE_FUNC MakeCompare,
    COMPARE_FUNC ModelCompare,
    COMPARE_FUNC YearCompare,
    COMPARE_FUNC RegCompare);
    
    
    list-array.c
    _________
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include "list-array.h"
    
    int ListInit(List *sList, Key key1, COMPARE_FUNC MakeCompare,
    COMPARE_FUNC ModelCompare,
    COMPARE_FUNC YearCompare,
    COMPARE_FUNC RegCompare)
    {
      // This is the quickest way to set
      // everything in the list to 0
      memset(sList, 0, sizeof(List));
    
      sList->ckey = key1;
    
      sList->MakeCompare = MakeCompare;
      sList->ModelCompare = ModelCompare;
      sList->YearCompare = YearCompare;
      sList->RegCompare = RegCompare;
      return SUCCESS;
    }
    This piece of code is the proof that you lost track of your code, especially of your function pointers:
    sList->FuncComp[0] = *(int*)MakeCompare;
    sList->FuncComp[1] = *(int*)ModelCompare;
    sList->FuncComp[2] = *(int*)YearCompare;
    sList->FuncComp[3] = *(int*)RegCompare;
    It doesn't make any sense. This is why you should ALWAYS, without exception, use typedefs when working with function pointers. This is also the reason why you should ALWAYS think about every cast you do. Casting basically should be kept to the absolute minimum.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  7. #7

    Thread Starter
    New Member
    Join Date
    Oct 2002
    Posts
    10
    Thanks expert, you are better than my teacher (Dr.!!!)

    if you can continue with me please,

    I tried this way to insert data to the list but it seems not working perfectly:

    int ListInsert(List *sList, char *make, char *model, char *year, char *reg)
    {
    int i = ListSize(sList);

    if (ListFull(sList) || sList == NULL){
    printf("Cannot append an entry to a full list.");
    return FAILURE;
    }else{

    malloc(sizeof(char)*( 1 + strlen(make)));
    strcpy(sList->temp->make, make);

    malloc(sizeof(char)*( 1 + strlen(model)));
    strcpy(sList->temp->model, model);

    malloc(sizeof(char)*( 1 + strlen(year)));
    *(int*)sList->temp->year = atoi(year);


    malloc(sizeof(char)*( 1 + strlen(reg)));
    strcpy(sList->temp->reg, reg);

    switch(sList->ckey){
    case 0:{
    if(sList->funComp[0] <= 0){

    while (i > 0 && sList->temp->year < sList->Cars[i-1]->year)
    {
    strcpy(sList->Cars[i]->make, sList->Cars[i-1]->make);
    strcpy(sList->Cars[i]->model, sList->Cars[i-1]->model);
    sList->Cars[i]->year = sList->Cars[i-1]->year;
    strcpy(sList->Cars[i]->reg, sList->Cars[i-1]->reg);
    i--;
    }
    strcpy(sList->Cars[i]->make, sList->temp->make);
    strcpy(sList->Cars[i]->model, sList->temp->model);
    sList->Cars[i]->year = sList->temp->year;
    strcpy(sList->Cars[i]->reg, sList->temp->reg);

    (sList->count)++;
    return SUCCESS;
    break;
    }
    case 1:{
    ;
    ;
    ;
    ;
    ;
    ;
    ;

    ;
    teach yourself as you can, when you get stuck ask and do not shy

  8. #8
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Are there any special requirements for this function except inserting an entry?

    Note: you must store the result of malloc somewhere!
    And you have another careless cast where you assign to the year.


    And to be honest, it's not hard to be better than a programming teacher.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  9. #9

    Thread Starter
    New Member
    Join Date
    Oct 2002
    Posts
    10
    Hi again, following are the instructions of how Insert function should work;

    Note: the previous declaration of Comparsion functions gave me error message "Redeclartion of function and did not work till I changed them to the previous states"

    * int ListInsert(List*, char *, char *, char *, char *);
    * - accepts a pointer to an existing List variable,
    * and 4 pointers to strings that represent the information
    * of the car to be added to the List. You will use the compare
    * function for the default ordering passed in at the ListInit stage
    * to find the correct place to insert the new structure. Ie. if
    * the Key is REG then the function passed in must compare the
    * registration of each structure.
    * - this function returns true if successful, and false
    * if unsuccessful
    *
    teach yourself as you can, when you get stuck ask and do not shy

  10. #10
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I think I now see the reason why this is called a list. It's tedious to implement using an array. Look into double-linked lists, they are more helpful in this case.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  11. #11
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Binary trees would be even better, but linked lists are easier.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  12. #12

    Thread Starter
    New Member
    Join Date
    Oct 2002
    Posts
    10

    Talking

    you are right list of array,, this the first part and the second part we will implement link-list with same instructions,

    how can I get help from double-linked lists.

    I am really in stuck using that function pointers and Insert function, I asked my teacher he said you need first to allocat a location for new entry and check wether the list is empty or it needs to put the new node at tail or head, I got stuck to solve that out.

    Could you give outlines to start at least with correct track please , as you saw I lose truck with cast and it's a hint that it was bad start with this subject.

    do the best if you can please, and thanks to have responded me
    teach yourself as you can, when you get stuck ask and do not shy

  13. #13
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    The problem is that it is complicated to insert an element at an arbitrary position in a normal array. This is why you should use a linked list.

    A linked list is basically two structures. A list structure:
    struct List {
    Node *head;
    Node *tail;
    // if you want you can add a count:
    int count;
    };
    and a Node structure:
    struct Node {
    Node *prev;
    DataType data;
    Node *next;
    };

    This is a double-linked list because it has both a prev and a next pointer. Single-linked lists only have the next pointer. This lets them save space, but they are slower and harder to implement.

    Linked lists are perfect to wrap in classes. I've attached an example linked list I've made a while ago. It's the simplest llinked list class I could think of that fulfills the following criteria:
    • Hide the Node structure from the user and provide abstract access via an iterator.
    • Expose a subset of the STL linked list function: clear, push/pop_back/front, insert, remove, begin, end
    • Provide a fully functional iterator class
    • Let it store any type through the use of templates.


    The code is not commented so you'll have to ask me if you have questions.
    Attached Files Attached Files
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  14. #14

    Thread Starter
    New Member
    Join Date
    Oct 2002
    Posts
    10

    Wink

    the attached file seems C++ or java, I am not sure, but what I need is Insert a Node to a struct using C language which is really very complicated.

    the requirement that we should implement both array and link-list.

    by the way thanks for all stuff you have furnished and talk to you with other troubles, byeeeeeeeeeeee
    teach yourself as you can, when you get stuck ask and do not shy

  15. #15
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    It's not very hard to convert it to C code. You can't hide things from the user anymore, but the data and the way it works remains the same.

    For the array:
    When you need to insert an element, search for the insert position in the array. Then use memmove(PointerToLocationWhereToInsert+1, PointerToLocationWhereToInsert, ByteSizeOfElementsRemaining) to create space for the new element. Then insert the element.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width