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);
}
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().