Linking two structures in C - c

I am trying to link 2 structures, one is a matrix and one is a single node. The connection should be a matrix that holds size and an array of rows with nodes connected between each other:
so a 3X3 matrix should look like this:
|Node|->|Node|->|Node|-> NULL
|Node|->|Node|->|Node|-> NULL
|Node|->|Node|->|Node|-> NULL
The question is how do I connect it properly?
Do I need to allocate the memory for the rows only or should I allocate the memory for all elemets and then connect them?
typedef struct cellNode {
int cell;
struct cellNode* next;
} Node;
typedef struct {
int numRows;
int numColumns;
Node** rows;
} Matrix;
Matrix* MatrixAdder(int row, int col, char mat)
{
Matrix temp=NULL;
int i,j;
if(!(temp=(Matrix*)malloc(sizeof(Matrix)));
exit(1);
temp->numRows=row;
temp->numColumns=col;
if (!(temp.rows[i]=(Node*)malloc((row)*sizeof(Node))));
exit (1);
printf("Please insert values for matrix %c:\n",mat);
for (i=0;i<row;i++)
{
if(!(temp->rows[i]=(Node*)malloc(sizeof(Node))))
exit (1);
printf("Enter row %d data\n",i);
for(j=0;j<col;j++)
{
scanf("%d",&temp->rows->cell);
temp->rows=temp->rows->next;
if(!(temp->rows=(Node*)malloc(sizeof(Node))))
exit (1);
}
temp->rows=NULL;
}
}

If you know how many nodes you need to allocate, then you can of course allocate them all in a single call to malloc (as a normal plain "dynamic array" of nodes) and then link them all together. All you need is to keep track of the pointer returned by malloc.
But you still need to allocate the array of pointers used for rows. So no matter what you need at least two allocations.
It could be dome something like this (using normal variables and not your structures):
int numRows = 3;
int numColumns = 3;
// Allocate all the nodes
Node *allNodes = malloc(sizeof *allNodes * numRows * numColumns);
// Allocate the array of pointers needed
Node **rows = malloc(sizeof *rows * numRows);
// Initialize the rows
for (int row = 0; row < numRows; ++row)
{
// if numColums == 3 then for
// row == 0 get a pointer to allNodes[0]
// row == 1 get a pointer to allNodes[3]
// row == 2 get a pointer to allNodes[6]
rows[row] = &allNodes[row * numColumns];
}
// Now create the linked lists
for (int row = 0; i < numRows; ++row)
{
// For numRows == 3, this will make node point to, in turn:
// allNodes[0]
// allNodes[3]
// allNodes[6]
Node **node = &rows[row];
// node will be pointing to a pointer to the *previous* node
// So start with 1 because that's then the *next* node in the list
for (int col = 1; col < numColumns; ++col)
{
// When row == 0 then:
// When col == 1 then link allNodes[0]->next to allNodes[1]
// When col == 2 then link allNodes[1]->next to allNodes[2]
// When row == 1 then:
// When col == 1 then link allNodes[3]->next to allNodes[4]
// When col == 2 then link allNodes[4]->next to allNodes[5]
// Etc...
(*node)->next = &allNodes[row * numColumns + col];
(*node) = &(*node)->next;
}
// Now head will be pointing to the lasts nodes next member
(*node) = NULL;
}
[Note: Code not tested!]
When finished you only have two pointers to free:
free(rows);
free(allNodes);
To understand exactly what's going on, if you're having trouble following along, I recommend you use a debugger together with a pen and some paper.
First of all draw a long rectangle for allNodes and divide it into numRows * numColumns number of sub-rectangles. Label them with their index (so the first becomes 0, the second 1 etc.). Then draw a second rectangle for rows and divide it into numRows sub-rectangles. Label these too with the indexes.
Now as you step along in the debugger, draw arrows between the sub-rectangles for form "pointers". For example with the first iteration of the first loop you draw an arrow from rows[0] to allNodes[0].
For the second loop, where the linked lists are created, draw another little rectangle and label it head. For each iteration of the outer linking loop you (erase) and draw an arrow from head to first rows[0], and so on.
Inside the inner linking loop (over columns) with the statement
(*head)->next = &allNodes[row * numColumns + col];
start at head and follow its arrow to rows. Then again follow the arrow to allNodes, and continue to follow any arrows until there are no more. Then draw an arrow from that element in allNodes to the next element in allNodes as indicated by row * numColumns + col. So for the first iteration you follow the arrow from head to rows[0], you follow that along to allNodes[0] where you draw an arrow to allNodes[1].
To understand why we use a pointer to a pointer for node and what (*node) = NULL is doing, then we need to draw how it looks like after the inner loop finishes. Again we use row == 0 as example.
+------+ +------------------+
| node | --> | allNodes[2].next | --> ???
+------+ +------------------+
By dereferencing node (as in (*node)) then we get to allNodes[2].next which we then can assign to be a NULL pointer.

Related

Using memmove to move element in array

I allocated a multi-dimensional array using malloc. After I process an element I have to delete it from the array and reallocate the correct amount of memory. So I used memmove to overwrite the array moving the elements that are in the next position with respect to the one I processed in its position.
float **dataset = (float**)malloc(CHUNK * sizeof(float *));
for (int i = 0; i < CHUNK; i++) {
dataset[i] = (float *) malloc((d + 1) * sizeof(float));
if(dataset[i] == NULL){
printf("Something went wrong in load_dataset(), memory allocation failed!");
exit(1);
}
}
[... filling the dataset and other stuff...]
/* now I want to move all the elements from the second one,
back of 1 position and then reallocate dataset
to have one less dimensoin*/
memmove(dataset[0], dataset[1], 20 * sizeof(float*));
But it only moves the first 4 elements.

Undefined behavior when deleting an element from dynamic array of structs

I have an n sized array of structs dynamically allocated, and each position of the array is an array too, with different sizes for each position (an array of arrays).
I created a function to delete a given array[index] but I'm facing some undefined behavior, for example:
If the array is of size 3, if I delete array[0],I can't access array[1]. This happens with other combinations of indexes too. The only way it works flawlessly is when I delete from end to start.
Here is the code I have:
Structures:
typedef struct point{
char id[5];
char type[5];
char color[10];
int x;
int y;
} Point;
typedef struct {
char lineID[5];
int nPoints;
Point *pt;
}railData;
typedef struct railway {
railData data;
}railway;
This is how the array was created:
headRail = (railway**)calloc(lineNum,sizeof(railway*));
And each Rail:
headRail[i] = (railway*)calloc(pointsNum,sizeof(railway));
These are the functions to delete a rail:
railway **delRail(railway **headRail, int j)
{
int nPts = 0;
if (!headRail)
{
puts(ERRORS[NULLPOINTER]);
return NULL;
}
// Number of rail points on jth rail
nPts = headRail[j]->data.nPoints;
// Free each rail point from jth rail
for (int i = 0; i < nPts; ++i)
{
free(headRail[j][i].data.pt);
}
// Free allocated memory for jth rail
free(headRail[j]);
return headRail;
}
And this is where I call the previous function:
railway **removeRail(railway **headRail)
{
char userID[20];
int index = 0;
// Quit if no rails
if (!headRail)
{
backToMenu("No rails available!");
return NULL;
}
// Get user input
getString("\nRail ID: ",userID,MINLEN,MAXLEN); // MINLEN = 2 MAXLEN = 4
// get index of the asked rail
getRailIndex(headRail,userID,&index);
if (index != NOTFOUND)
{
headRail = delRail(headRail, index);
// Update number of rails in the array (global var)
NUMOFRAILS--;
backToMenu("Rail deleted!\n");
}
else
backToMenu("Rail not found!");
return headRail;
}
So my question is how can I modify my code so that when position i is eliminated, all other indexes are shifted left and the last position, which would be empty, is discarded (something like realloc but for shrinking)
Is what I'm asking doable without changing the array's structure?
When removing element i, do memmove all the data from i+1 to i to the end of the array and then realloc with the size decremented by 1.
Note that arrays in C do not track their size in any way, so you need to pass the size by an external way.
Your data abstraction is strange. I would expect that headRail[j][0].data.nPoints is used to store the number of points inside the headRail[j][0].data structure, yet there you store the count of headRails in the j row headRail[j][<this count>]. I would advise to rewrite the abstraction, have one "object" for the railway and another for hadling two dimensional arrays of railways with dynamic sizes in all directions.
Like:
railway **delRail(railway **headRail, int j)
{
...
// this is strange, it's equal to
// nPts = headRail[j][0].data.nPoints;
// dunno if you mean that,
// or if [j][0].data.nPoints refers to the size of
// headRail[j][0].data.pt or to the size of the whole array
size_t nPts = headRail[j]->data.nPoints;
for (size_t i = 0; i < nPts; ++i) {
free(headRail[j][i].data.pt);
}
free(headRail[j]);
// note that arrays in C does not know how many elements are there in the array
// so you typically pass that along the arguments, like
// railway **delRail(railway **headRail, size_t railcount, int j);
size_t headRailCount = lineNum; // some external knowledge of the size
memmove(&headRail[j], &headRail[j + 1], (headRailCount - j - 1) * sizeof(*headRail));
void *pnt = realloc(headRail, (headRailCount - 1) * sizeof(*headRail));
if (pnt == NULL) return NULL; // that would be strange
headRail = pnt; // note that the previous headRail is no longer valid
--lineNum; // decrement that object where you store the size of the array
return headRail;
}
What about some encapsulation and more structs instead of 2d array? 2d arrays are really a bit of pain for C, what about:
typedef struct {
// stores a single row of rail datas
struct railData_row_s {
// stores a pointer to an array of rail datas
railData *data;
// stores the count of how many datas of rails are stored here
size_t datacnt;
// stores a pointer to an array of rows of rail datas
} *raildatas;
// stores the size of the pointer of rows of rail datas
size_t raildatascnt;
} railway;
The count of mallocs will stay the same, but thinking about data will get simpler. And each pointer that points to an array of data has it's own size tracking variable. An allocation might look like this:
railway *rail_new(size_t lineNum, size_t pointsNum) {
railway *r = calloc(1, sizeof(*r));
if (!r) { return NULL; }
// allocate the memory for rows of raildata
r->raildatascnt = lineNum;
r->raildatas = calloc(r->raildatascnt, sizeof(*r->raildatas));
if (!t->raildatas) { /* error hadnling */ free(r); abort(); }
// for each row of raildata
for (size_t i = 0; i < r->raildatascnt; ++i) {
struct railData_row_s * const row = &r->raildatas[i];
// allocate the memory for the column of raildata
// hah, looks similar to the above?
row->datacnt = pointsNum;
row->data = calloc(row->datacnt, sizeof(*row->data));
if (!row->data) { /* error ahdnling */ abort(); }
}
return r;
}

Fastest way to remove huge number of elements from an array in C

I have dynamic array that contains thousands of elements or even more, in order not to consume a large size of memory, I can remove unwanted elements from it (i.e elements have been used and no need for them any more) so from the beginning I can allocate a smaller memory size by estimating the maximum required size after removing the elements each time.
I use this way but it takes a very very long time to finish, sometime takes 30 minutes!
int x, y ;
for (x = 0 ; x<number_of_elements_to_remove ; x++){
for (y = 0 ; y<size_of_array; y++ ){
array[y] = array[y+1];
}
}
Is there a faster way than this?
Instead of removing elements one at a time, with two loops making for an O(n2) solution, you can make a single loop, with a single read and a single write index. Go through the array, copying items as you go:
int rd = 0, wr = 0;
while (rd != size_of_array) {
if (keep_element(array[rd])) {
array[wr++] = array[rd];
}
rd++;
}
At the end of the loop wr is the number of elements kept in the array.
as I noticed you want to only delete elements from the start of the array, try this:
int x;
for(x = 0 ; x< size_of_array - number_of_elements_to_remove; x++)
array[x] = array[number_of_elements_to_remove + x];
this way you're using one for loop which reduces the complexity alot
It seems you essentially do
int y;
for (y = 0; y<size_of_array; y++){
array[y] = array[y+numbre_of_elements_to_remove];
}
The above should be faster, but there are still some caveats / problems with your code (e.g., access beyond the end od the array).
Here is the code to defragment the array.
int sparse_to_compact(int*arr, int total, int*is_valid) {
int i = 0;
int last = total - 1;
// trim the last invalid elements
for(; last >= 0 && !is_valid[last]; last--); // trim invalid elements from last
// now we keep swapping the invalid with last valid element
for(i=0; i < last; i++) {
if(is_valid[i])
continue;
arr[i] = arr[last]; // swap invalid with the last valid
last--;
for(; last >= 0 && !is_valid[last]; last--); // trim invalid elements
}
return last+1; // return the compact length of the array
}
I copied the code from this answer.
I think more efficient way is to use a link-list of buckets. And the buckets are managed by bit-string memory manager. It is like the following,
struct elem {
uint32_t index; /* helper to locate it's position in the array */
int x; /* The content/object kept in the array */
}
Suppose, our array content is int and it is encapsulated in a structure named struct elem.
enum {
MAX_BUCKET_SIZE = 1024,
MAX_BITMASK_SIZE = (MAX_BUCKET_SIZE + 63) >> 6,
};
struct bucket {
struct bucket*next; /* link to the next bucket */
uint64_t usage[MAX_BITMASK_SIZE]; /* track memory usage */
struct elem[MAX_BUCKET_SIZE]; /* the array */
};
A bucket is defined as an array of struct elem and usage mask.
struct bucket_list {
struct bucket*head; /* dynamically allocated bucket */
}container;
And a bucket list is a linked list containing all the buckets.
So we need to write memory manager code.
At first we need new bucket to be allocated when needed.
struct bucket*bk = get_empty_bucket(&container);
if(!bk) { /* no empty bucket */
/* allocate a bucket */
struct bucket*bk = (struct bucket*)malloc(sizeof(struct bucket));
assert(bk);
/* cleanup the usage flag */
memset(bk->usage, 0, sizeof(bk->usage));
/* link the bucket */
bk->next = container.head;
container.head = bk;
}
Now as we have the bucket we need to set the value in the array when needed.
for(i = 0; i < MAX_BITMASK_SIZE; i++) {
uint64_t bits = ~bk.usage[i];
if(!bits) continue; /* no space */
/* get the next empty position */
int bit_index = _builtin_ctzl(bits);
int index = (i<<6)+bit_index;
/* set the array value */
bk->elem[index].index = index;
bk->elem[index].x = 34/* my value */;
bk.usage[i] |= 1<<bit_index; /* mark/flag the array element as used */
}
Deleting the array elements is easy as to mark them unused. Now when all the elements in a bucket is unused we can delete the bucket from the link-list.
We can sometimes defragment buckets or optimize them to fit in smaller space. Otherwise when we assign new elements we can select more crowded buckets over less crowded one. When we delete we can swap the element of less crowded one into more crowded one.
It is possible to delete elements of array in efficient way,
int remove_element(int*from, int total, int index) {
if(index != (total-1))
from[index] = from[total-1];
return total; // **DO NOT DECREASE** the total here
}
It is done by swapping the element with the last value.

Getting the values of linked list with loops

I have to create a function who can get the value of a matrix wich take the form of a double linked list. Here is the structures of the matrix
typedef struct row {
unsigned int indiceRow;
struct row * next;
struct col * data;
} row;
typedef struct col{
double value;
unsigned int indiceColumn;
struct col * next;
} col;
typedef struct matrix{
int nRows;
int nCols;
struct row * rowFirst;
}matrix;
the structure matrix represent the top of the linked list and contain the total number of rows and columns and a variable row wich point to the first node of the list of row nodes. the row nodes contain the number of the row of the matrice, a variable row called next wich represent the next line of the matrix and a variable data point to another list of col nodes. Those col nodes contains the number of the column, the value at those coordonates(row,column) and the a col next. only the values different of zero have to be in the col linked list.
To get the value of a precise point of the matrix I created the function sp_get. It take a structure matrix, the line and column I'm looking for and a double variable as argument. It returns 0 when it works and update the variable double *val with the value I'm looking for.
int sp_get( struct matrix *mat, unsigned int rows, unsigned int col, double *val){
row * temps = (row*)malloc(sizeof(row));
temps = mat->rowFirst;
while(temps->indiceRow!= rows){
temps = temps->next;
}
while(temps->data!= NULL && temps->data->indiceColumn!= col && temps->data->next!=NULL){
temps->data = temps->data->next;
}
if(temps->data->indiceColumn == col){
*(val) = temps->data->value;
}
else{
*(val) = 0.0;
}
return 0;
First I create a row variable to run through the matrix, then I look for the good row and then for the good column. If I can't find the good column it means that the value is 0.
When I use the function to look for one value, it works well, and always return the good value.(tempMatrix is a matrix variable and contain the linked list)
double * vall =(double*)malloc(sizeof(double));
sp_get(tempMatrix, 2, 3, vall);
but when I'm using the function with a double loop for I don't have the same results and I can't not explain why...
double * vall =(double*)malloc(sizeof(double));
int i;
int j;
for(i=1;i<=tempMatrix->nRows;i++){
for(j=1; j<=tempMatrix->nCols;j++){
sp_get(tempMatrix,i,j,vall);
printf(" %f ", *(vall));
}
printf("\n");
}
Here are the result I get with the loops
and here are the results I should get
It might be a proble of memory leak, I don't know where it comes from.
Thanks in advance for your help!
Just in sp_get alone the following problems abound:
Memory the first two lines.
Anytime you see something like this in successive lines in C:
ptr = malloc(...)
ptr = <something else>
it is always a memory leak.
Updating the column header rather than simply enumerating it
Once you find the row you seek, you then do this:
while(temps->data!= NULL &&
temps->data->indiceColumn!= col &&
temps->data->next!=NULL)
{
temps->data = temps->data->next;
}
Ask yourself, what is temps->data = ... actually updating? It is changing the temps->data pointer to point to its own next, which means what temps->data pointed to prior is gone. That's fine if temps->data is a temporary pointer, but it isn't. It is the data member in the row struct you worked so hard to find in the prior loop.
Potential NULL pointer dereference
You may think having this:
while(temps->data!= NULL &&
temps->data->indiceColumn!= col &&
temps->data->next!=NULL)
for the while-condition in your loop will harbor safety from temp-data being NULL for the code that follows:
if(temps->data->indiceColumn == col)
{
*(val) = temps->data->value;
}
but if it did, then why bother with the first clause (which is correct, btw). It appears the addition of the last clause (temps->data->next!=NULL) was an effort to stave off crashes. That isn't the way to do it.
Minor: Hiding type col with parameter col
Needs little explanation. See your var names.
Minor: There is no need to dynamically allocate the out-parameter as you're using it.
Your code do to this:
double * vall =(double*)malloc(sizeof(double));
int i, j;
for(i=1;i<=tempMatrix->nRows;i++)
{
for(j=1; j<=tempMatrix->nCols;j++)
{
sp_get(tempMatrix,i,j,vall);
printf(" %f ", *(vall));
}
printf("\n");
}
Can just as easily do this:
double val = 0.0;
int i, j;
for(i=1;i<=tempMatrix->nRows;i++)
{
for(j=1; j<=tempMatrix->nCols;j++)
{
sp_get(tempMatrix,i,j,&val); // note address-of operator
printf(" %f ", val);
}
printf("\n");
}
Updated sp_get
I'm pretty sure this is what you're trying to do. The following will return 0 if the indexed values found and retrieved, otherwise it returns -1 and the out-parameter is set to 0.0.
int sp_get( struct matrix const *mat, unsigned int rows, unsigned int cols, double *val)
{
// prime to 0.0
*val = 0.0;
if (!mats)
return -1;
// walk the row table
struct row const *row_ptr = mat->rowFirst;
while (row_ptr && row_ptr->indiceRow != rows)
row_ptr = row_ptr->next;
// leave now if we didn't find the row.
if (!row_ptr)
return -1;
struct col const *col_ptr = row_ptr->data;
while (col_ptr && col_ptr->indiceColumn != cols)
col_ptr = col_ptr->next;
if (!col_ptr)
return -1;
*val = col_ptr->value;
return 0;
}
Note we modify nothing in the actual matrix, so the entire thing, including all pointers we use to index within it, can be const (and should be).
Best of luck.

C malloc error freeing struct

I've just re-start learning C, but i'm really confused with some memory management details.
I'm getting
pointer being freed was not allocated ... Abort trap
for the code below. Do i really need 1 free per malloc? Why my code is wrong?
Thanks!
#define N 9
typedef struct
{
int MAX_LIST_SIZE;
int length;
int *ini;
}List;
/* allocates new List and its data */
List *newList(int size)
{
List *list = malloc(sizeof(List));
list->MAX_LIST_SIZE = size;
list->length = 0;
list->ini = malloc(sizeof(int) * size);
return list;
}
/* add some value to the list */
void addList(List *list, int val)
{
if (list->length < list->MAX_LIST_SIZE)
list->ini[list->length++] = val;
else
fprintf(stderr, "Error: add(): List is full.\n");
}
/* get an array of N*N lists malloc-ed Lists */
List *gridList()
{
int i, j;
List *cells = malloc(sizeof(List) * N * N);
for (i = 0; i < N * N; i++)
{
/* malloc is called inside NewList()*/
cells[i] = *newList(N);
for (j = 0; j < N; j++)
addList(&cells[i], j + 1);
}
return cells;
}
/* inside main */
List *cells = gridList();
/* use cells ... */
/* free */
for (i = 0; i < N * N; i++)
{
free(cells[i].ini);
/* line below causes CRASH */
free(&cells[i]);
}
You do :
cells[i] = *newList(N);
which sets each element in cells to a copy of the list dynamically allocated by newList. So newList dynamically allocates a list, then you take the pointer to that dynamically allocated List, dereference it, and copy it into cells[i]. So then later on when you go to free() each element:
free(&cells[i]);
It doesn't work because each element in cells[i] is a List, not a List * (list pointer) allocated by malloc().
So you have two options. One (bad one) is to just remove that last free() line since there's nothing to free. However, this just covers up a larger problem which is that you now have memory leaks because you can't go back and free the dynamically allocated Lists created with newList().
Instead it's likely you want to have an array of pointers to the lists, which you can do by changing it to:
List **cells = malloc(sizeof(List*) * N * N);
so that cells[i] refers to a List *. newList() returns such a pointer, so you would change that line to:
cells[i] = newList(N);
similarly, addList() takes such a pointer, so you'd simply change that line to:
addList(cells[i], j + 1);
since &cells[i] would pass it the address of the pointer, which is not what you want.
Finally, change the free statements to:
free(cells[i]->ini); // ->init because cells[i] is now a pointer to a List, List *
free(cells[i]);
The problem is you are allocating an array of lists, copying the full contents of your lists into the array elements, and then trying to free them. The original allocated List records are a memory leak, and the free calls are indeed trying to free memory that was not malloc'ed (or more exactly were malloc'ed in a single big block).
You want an array of pointers to pointers to hold your lists:
/* get an array of N*N lists malloc-ed Lists */
List **gridList()
{
int i, j;
// VV note change here
List **cells = malloc(sizeof(List*) * N * N);
for (i = 0; i < N * N; i++)
{
/* malloc is called inside NewList()*/
cells[i] = newList(N); // << Note change here.
for (j = 0; j < N; j++)
addList(cells[i], j + 1);
}
return cells;
}
/* free */
for (i = 0; i < N * N; i++)
{
free(cells[i]->ini); // << and here
/* line below causes CRASH */
free(cells[i]); // << and here
}
free(cells);

Resources