I don't understand why the head node keeps on changing after each call to this function [closed]

StackOverflow https://stackoverflow.com/questions/23645639

  •  22-07-2023
  •  | 
  •  

Question

I am trying to write a program to express a stream of input for the non-zero elements of a matrix into a Compressed Sparse Representation. The function csr is being called every time a new non-zero number is encountered in the main function. The printf statement is giving me different values after each call to the function. The head node(v_h & a_h) is not being updated anywhere except in the first if statement where the list is empty. 'a' and v are two linked lists of type re_ar. ia has been initialized with ia[i].a=NULL for i:0,n-1

struct re_ar{
 float x;
 struct re_ar *nxt;
};                          //structure for each node of a list containing real numbers

typedef struct re_ar re_ar;

struct in_ar{
re_ar *a;
re_ar *v;
}; //structure for each node of an array containing pointers to two lists of type re_ar 

typedef struct in_ar in_ar;
in_ar *ia;                      //ia is an array
re_ar *a_h=NULL;re_ar *a_t=NULL;
re_ar *v_h=NULL;re_ar *v_t=NULL; //a_h, v_h are head nodes for lists a & v
int n;                           //a_t, v_t are tail nodes
void csr(float d, int r_i, int c_i) //r_i-row number, c_i-column number, d- entry
   {
   re_ar a_n;
   re_ar v_n;                    //a_n v_n are new nodes

   a_n.nxt = NULL;
   v_n.nxt = NULL;
   a_n.x   = d; 
   v_n.x   = c_i;              //assigning data to both nodes

   if(a_h == NULL)             //Checking if the list is empty
      {
      a_h = &a_n; 
      v_h = &v_n;
      a_t = &a_n; 
      v_t = &v_n;             //Connecting head and tail nodes to the first node
      (ia[r_i].a) = &a_n;
      (ia[r_i].v) = &v_n;    //Pointing ia[r_i] to the first node of both the lists
      }
   else                       //For non-empty cases
      {
      a_t->nxt=&a_n; 
      a_t=&a_n;
      v_t->nxt=&v_n; 
      v_t=&v_n;              //Adding nodes to the list
      if(ia[r_i].a==NULL)    //Checking if ia[r_i] has been already pointed to a node
         {
         ia[r_i].a=&a_n;
         ia[r_i].v=&v_n;     //Connecting ia[r_i] to the current node
         }
      }

   printf("%f", v_h->x);
   }
Was it helpful?

Solution

The problem with the question code is that new nodes are built on the stack.
(As indicated by 'Brett Hale')

re_ar a_n;
re_ar v_n;

Being that a_n and v_n are 'automatic' stack variables, their scope (and existence) is limited to the function in which they reside. When the csr() function returns, the memory occupied by a_n and v_n will be used by other stack structures.

Perhaps it would be appropriate to allocate storage for the new nodes on the heap; something like this:

re_ar *a_n = NULL;
re_ar *v_n = NULL;

a_n=malloc(sizeof(*a_n));
if(NULL == a_n)
   /* Handle malloc() failure here. */;

v_n=malloc(sizeof(*a_n));
if(NULL == v_n)
   /* Handle malloc() failure here. */;

a_n->nxt = NULL;
v_n->nxt = NULL;
a_n->x   = d; 
v_n->x   = c_i;
...

Then, the new list nodes will persist beyond the life of csr().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top