0

I have to save in an array the address of some data. Every data is a structure of type "dagNode". To do my work I visit a list, and I count the number of data that I want to record its address so I allocate the right space in the memory, and finally I re-visit the list and save the address of some data.

    struct dagNode *buildBST(struct dagNode *rootList){
    struct dagNode *head, **xTest;
    head = rootList;
    int numXtest=0;

    rootList = nextNode(TYPE_XTEST, rootList);

    while ( !IS_TERMINATED( rootList ) ){   // first visit
        numXtest++;
        rootList = nextNode(TYPE_XTEST, rootList); }

    xTest = (struct dagNode **) malloc( sizeof(struct dagNode ) * numXtest);
    int i=0; rootList = nextNode(TYPE_XTEST, head);

    for(i=0; i<numXtest; i++){      // second visit, saving the address of some datas
        rootList = nextNode(TYPE_XTEST, rootList);
        xTest[i] = rootList; i++;
    >>> printf("t=%d,val=%d\t", xTest[i]->nodeType, xTest[i]->val); } // segmentation fault

    return head;
    }

EDIT:

    struct dagNode *nextNode(int typeOfNextNode, struct dagNode *node){
        if (IS_TERMINATED(node)){   return node;    }
        node = node->next;
        if (typeOfNextNode == TYPE_EDGE_OR_GAP){
            while (!IS_TERMINATED(node) && !IS_AN_EDGE(node) && !IS_A_GAP(node)){
                node = node->next;  }
               }else
        {
            while (!IS_TERMINATED(node) && (node->nodeType != typeOfNextNode)){
                node = node->next;}
        }
        return node;    }
4
  • Show us the nextNode function. Commented Feb 14, 2012 at 14:35
  • You can isolate the problem by running your code in the debugger. Commented Feb 14, 2012 at 14:35
  • 3
    That is the most inscrutable code layout I've seen in a long time. Please, for everyone's sanity's sake, adopt a more orthodox format. At the least, the if and the else should align vertically, and the } should be at the start of the line, not hidden at the end. Commented Feb 14, 2012 at 14:52
  • Never typecast the result of malloc in C. Read this. Commented Feb 14, 2012 at 15:23

3 Answers 3

2

nextNode() seems to be the obvious culprit.

Edit: Note that you are also incrementing i twice per iterations. This will certainly crash.

Sign up to request clarification or add additional context in comments.

1 Comment

This is the most probable cause of the trouble. In the loop, there is a hidden increment xTest[i] = rootList; i++; just before the print. So, you skip past the pointer you've just set up before you print the data. Since the for loop control also increments i, you (the OP) should probably just delete the i++; inside the loop. The memory issue identified by @Blagovest is also something to deal with, but if sizeof(struct dagNode) >= sizeof(struct dagNode *) (which is inevitable since the nodes contain a pointer), the defect only wastes memory rather than causing crashes.
1

There is a mismatch between the type of the xTest pointer and the size you allocate in malloc. If xTest is of type struct dagNode **, the proper allocation should be:

xTest = malloc(sizeof(struct dagNode *) * numXtest);

Probably you want to allocate numXtest pointers to a struct, not numXtest structs.

Comments

0

I'm sorry but this post does not answer the question. I merely want to give you an example of an alternative coding style. Pick up what you like from it.

I haven't changed the meaning of the code, except for the removal of the most obvious bugs already pointed out in other answers/comments.

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
  ...
} dagNode;

dagNode* buildBST (dagNode* rootList)
{
  dagNode*  head;
  dagNode** xTest;
  int numXtest=0;
  int i=0;

  head = rootList;
  rootList = nextNode(TYPE_XTEST, rootList);

  while (!IS_TERMINATED(rootList))               // first visit
  {
    numXtest++;
    rootList = nextNode(TYPE_XTEST, rootList);
  }

  xTest = malloc(sizeof(dagNode) * numXtest);
  rootList = nextNode(TYPE_XTEST, head);

  for(i=0; i<numXtest; i++)                      // second visit, saving the address of some datas
  {      
    rootList = nextNode(TYPE_XTEST, rootList);
    xTest[i] = rootList;

    printf("t=%d,val=%d\t", 
           xTest[i]->nodeType,
           xTest[i]->val);
  }

  return head;
}


dagNode *nextNode (int typeOfNextNode, dagNode *node)
{
  if (IS_TERMINATED(node))
  {
    return node;
  }

  node = node->next;

  if (typeOfNextNode == TYPE_EDGE_OR_GAP)
  {
    while ( !IS_TERMINATED(node) &&
            !IS_AN_EDGE(node) &&
            !IS_A_GAP(node) )
    {
      node = node->next;
    }
  }
  else
  {
    while ( !IS_TERMINATED(node) &&
            (node->nodeType != typeOfNextNode) )
    {
      node = node->next;
    }
  }

  return node;
}

1 Comment

Thanks for your post, i'm following your (better) style in the future.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.