Thread: Malloc problem

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    20

    Post Malloc problem

    Hi, I'm getting a crash on the routine on a device and i'm not sure why:

    I have the following structures:

    Code:
    struct NodeSlotFrame
    {
      word addr;
      byte slot;
      byte frame;
      struct NodeSlotFrame* next;
    };
    
    typedef struct
    {
      struct NodeSlotFrame own;
      byte nrOfNeighbours;
      struct NodeSlotFrame neighbours;
      byte nrOfHiddenNodes;
      struct NodeSlotFrame hiddenNodes;
    }INF;

    And in a function i try to have dynamic memory allocation:

    Code:
    word extractINF(byte* src, INF* dest)
    {
    ...
      pNode = &dest->neighbours
      //Get the remote neighbourhood's information
       for(i = 0;i < dest->nrOfNeighbours;i++)
       {
    	//Allocate memory for neighbours table
    	pNode->next = (struct NodeSlotFrame *) malloc(sizeof(struct NodeSlotFrame));
            ...		
    	pNode = pNode->next;
       }
    ...
    }
    I can't debug the system so it's hard for me to know what's exactly going on. Any ideas ?

    Thanks a million

    Inderjit

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    This is not the right way to implement a linked list. The neighbours field of the INF struct should be a pointer, not a real structure. It points to the head of the list.

    Furthermore, I do not see the code that makes sure the last node of the list has a NULL next pointer. So the crash probably comes when you try to free this thing. It could be crashing at the head (which isn't dynamically allocated) or the tail (which is uninitialized). Or you could be walking off the end of the list somewhere, again, because you didn't terminate the list with a NULL next pointer.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > struct NodeSlotFrame neighbours;
    Why isn't this a pointer?

    There is no actual problem with it, it's just that if you try and free it, you're in big trouble. In other words, the first node is allocated differently from all the other nodes, so it always creates special case coding problem for later on.

    Essentially,
    struct NodeSlotFrame *neighbours;
    is a pointer to the list of neighbours. If this pointer is NULL, then you have no neighbours.

    To get a single neighbour, you do
    dest->neighbours = newNodeSlot(); // see below

    To append more neighbours onto the end of the list, first find the node which has node->next == NULL. Again, create a simple function which performs this very specific task.

    Code:
    struct NodeSlotFrame *newNodeSlot ( void ) {
        struct NodeSlotFrame *slot = malloc ( sizeof *slot );
        if ( slot ) {
            // initialise ALL data elements
            slot->next = NULL;
        }
        return slot;
    }
    I would suggest you read up on how linked lists work.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Apr 2007
    Posts
    20
    Thanks for the reply. My mistake, I got lost in the code that I forgot the obvious...

    Sorry for the delay, I've been away. I'll try it now
    Last edited by freeindy; 05-02-2007 at 10:02 AM.

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    20
    Hi again,

    I changed the structure to this:

    Code:
    typedef struct
    {
      word addr;
      byte slot;
      byte frame;
    }NodeSlotFrame;
    
    struct NSFList
    {
      NodeSlotFrame nsf;
      struct NSFList *next;
    };
    
    
    typedef struct
    {
      NodeSlotFrame own;
      byte nrOfNeighbours;
      struct NSFList *neighbours;
      byte nrOfHiddenNodes;
      struct NSFList *hiddenNodes;
    }INF;
    And then I allocate new node like this:



    Code:
    void myfunction()
    {
            struct NSFList* neighbour = dat.inf.neighbours;
    
            if(dat.inf.nrOfNeighbours == 0)
    	{
    		dat.inf.neighbours = (struct NSFList*) malloc(sizeof(struct NSFList));
    		dat.inf.neighbours->next = NULL; //first node
    
    		//Keep the information of new node
    		memcpy(&dat.inf.neighbours->nsf, &rDat.inf.own, sizeof(NodeSlotFrame));
    
    		//Increase the count
    		dat.inf.nrOfNeighbours++;
    
    		return;
    	}
    
            //SEARCH THE LIST
            while (neighbour->next != NULL)
            {
                  ...
            }
    
    
            if(newNeighbour == TRUE)
    	{
    		//Memeory for new neighbour
    		neighbour->next = (struct NSFList*) malloc(sizeof(struct NSFList));
    		neighbour->next->next = NULL; //This is the last node
    
    		//Add to the list
    		memcpy(&neighbour->next->nsf, &rDat.inf.own, sizeof(NodeSlotFrame));
    		
    		//Increase the count
    		dat.inf.nrOfNeighbours++;
    	}
    }
    I am assuming that this should be correct. if not, please let me know. I have done link lists many times but it's always confusing when it's done in c or c++. I also problem debugging the algorithm in KDevelop with g++ (Which is not the compiler for the actual device) and am not sure where the problem lies. I wish do debug it directly for the device but that is just not possible at the moment...

    I can't pass parameters I'm afraid so please accept the there are no functions for adding/removing items. I'm working in NesC, a flavor of C for Wireless Sensor Networks and it doesn't 'allow' passing parameters directly.

    Thanks again

    Inderjit

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > I'm working in NesC
    You mean this - http://en.wikipedia.org/wiki/NesC ?

    > and it doesn't 'allow' passing parameters directly.
    Strange, the website says it's an extension to ANSI-C
    Removing parameter passing seems a huge backward step, not an extension.

    The code seems OK, but you're duplicating the work in a few places.
    Compare with
    Code:
    void myfunction()
    {
        struct NSFList* new = malloc( sizeof *new );
        if ( new ) {
            /* fully construct a new node before doing anything else */
            new->next = NULL;
            new->nsf = rDat.inf.own;    /* replace memcpy, if they really are the same type */
    
            /* start of a new list, or append to existing list */
            if ( dat.inf.nrOfNeighbours == 0 ) {
                dat.inf.neighbours = new;
            } else {
                struct NSFList* temp = dat.inf.neighbours;
                while ( temp->next != NULL ) temp = temp->next; /* find the tail */
                temp->next = new;                               /* append */
            }
    
            dat.inf.nrOfNeighbours++;
        }
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    20
    Thanks for the code. Looks a lot better. Regarding NesC. You're right, it is possible but only if you create an component. The reason goes in basic implementation of a nesc/tinyos design. Creating a real-time app on tinyos with nesc, it is recommended to create a job split into many tasks for avoidance in blocking the system.

    Inderjit

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  2. Replies: 12
    Last Post: 06-24-2005, 04:27 PM
  3. malloc and realloc
    By odysseus.lost in forum C Programming
    Replies: 3
    Last Post: 05-27-2005, 08:44 AM
  4. freeing problem with concurrent processes
    By alavardi in forum C Programming
    Replies: 2
    Last Post: 03-07-2005, 01:09 PM
  5. half ADT (nested struct) problem...
    By CyC|OpS in forum C Programming
    Replies: 1
    Last Post: 10-26-2002, 08:37 AM