0

I'm trying to type a function that takes 2 linked list. One has the values to be printed and the second has positions for the linked list values to be printed. It gives me an error that i put as comment in the code.

Structs

typedef int Item;
typedef struct node_struct * link;
typedef struct list_struct * list;

struct node_struct {
    Item item;
    link next;
};

struct list_struct {
    link first;
    int length;    
};

Function:

list sublist(list A, list pos_list) {
    link tempOne;
    link tempTwo;
    link node = malloc(sizeof *node);
    tempOne = pos_list->first;
    tempTwo = A->first;
    int counter;
    while(tempOne->next != NULL)
    {
        counter = 0;
        while(counter < tempOne->item && tempOne->next != NULL)
        {
            tempTwo = tempTwo->next;
            counter = counter+1;
        }
        node->item = tempTwo->item; //EXC_BAD_ACCESS code:1
        node = node->next;
        tempTwo = A->first;
        tempOne = tempOne->next;
        counter = 0;
    }
    return node;
Abeer
  • 69
  • 5
  • 2
    Welcome to StackOverflow! Could you please post a [minimal, complete, and verifiable example](http://stackoverflow.com/help/mcve) including a main function which calls `sublist` and shows the issue? Thanks! – AlexPogue Oct 01 '16 at 19:28
  • Getting that error almost certainly means that one of `node` and `tempTwo` is a null pointer. I also think it means you're working on a Mac. – Jonathan Leffler Oct 01 '16 at 19:30
  • 3
    See also: [Is it a good idea to `typedef` pointers?](http://stackoverflow.com/questions/750178/is-it-a-good-idea-to-typedef-pointers) — the succinct answer is 'No'. – Jonathan Leffler Oct 01 '16 at 19:31

1 Answers1

0

There are bunch of bad practices in the code which makes understanding (and hence debugging and maintaining) such code very difficult for you and for us.

  • You are creating a pointer typdef when there is no intention to hide the actual data behind the pointer
  • You are creating a linked list of positions and a linked list of data, using the same data type. I understand in your case both are int, but then don't use the misleading typedef int Item and simply stick to using int
  • tempOne and tempTwo are probably the worst naming options in this case, not only for calling the variables with non-intuitive names like temp, but also calling the first arg as Two and second arg as One - as counter-intuitive as it can get
  • I can see cases where you use 2 different structures node_struct (which frankly I would call node) and list_struct see node_structcomment), but in this example, you don't need list_struct, it only adds more confusion to the code.
  • You should really do the "find" job (the inner for loop)in a separate function, so you can easily handle errors, and not confuse the inner loop with the outer loop

With that out of the way, You haven't specified if the pos_list actually contains relative positions (position from previous position) or absolute positions (like array index). I will assume it is absolute position.

after you do node = node->next; you need to malloc it again. Or rather just malloc it before using it on line node->item = tempTwo->item; and get rid of the malloc out side the loops

I don't have a c compiler handy, so couldn't test it. But I don't see any other issues

EDIT

I noticed that the return value for sublist is always just the last node, instead of the first node in the linked list - this is obviously going to be a problem too.

Below is how I would write this code. Remember, this is not a debugged and tested code, but mere expression of the idea (first draft if you will)

typedef struct Node_ Node;

struct Node_ {
    int Item;
    Node* Next;
};

Node* GetNodeAt(Node *dataList, int indx) {
    for (int i = 0; i < indx && dataList != NULL; ++i)
        dataList = dataList->Next;
    return dataList;
}

Node* SubList(Node *dataList, Node *posList) {
    Node* origDataList = dataList;

    Node *currentRetNode = malloc(sizeof(Node));
    Node *prevRetNode = NULL, *returnList = currentRetNode;

    while (posList->Next != NULL) {
        // Find the node in dataList
        Node *node = GetNodeAt(dataList, posList->Item);

        // create/manage the linked list to be returned
        prevRetNode = currentRetNode;
        currentRetNode->Next = malloc(sizeof(Node));
        currentRetNode->Item = node->Item;
        currentRetNode = currentRetNode->Next;

        posList = posList->Next; // move to the next index
    }

    free(currentRetNode);

    if (prevRetNode == NULL)
        returnList = NULL;
    else
        prevRetNode->Next = NULL;

    return returnList;
}
Vikhram
  • 4,294
  • 1
  • 20
  • 32