Accessing a struct within array within a struct - c

What's the correct way of accessing (with a pointer) a variable within a struct within an array within a struct?
I's like to get to variables x and y within position2D with a pointer from function()? Note that I'm traversing the nodes (and the points) in function(), and was hoping to write something like:
draw_point(p->vertices[i]->x, p->vertices[i]->y);
but that doesn't seem to work.
typedef struct Position2D{
uint8_t x;
uint8_t y;
} position2D;
typedef struct Node{
int num;
position2D vertices[4];
struct Node *next;
} node;
/* initialisation: */
node *next1 = NULL; //should be empty
node node1 = {1, {{0,0}, {5,0}, {5,5}, {0,5}}, &next1};
node *next0 = &node1;
node node0 = {0, {{0,10}, {10,10}, {10,15}, {0,15}}, &next0};
node *start = &node0;
/*traverse all nodes and their inner vertices arrays: */
void function(void){
node *p;
for(p = start; p != NULL; p = p->next){
int i;
for (i=0; i<4; i++){ //traverse their four points
//How to get to the x and y at this line?
}
}

vertices is a normal structure variable, not of struct pointer type. While accessing x and y use dot . operator instead of -> operator
Replace below statement
draw_point(p->vertices[i]->x, p->vertices[i]->y);
with
draw_point(p->vertices[i].x, p->vertices[i].y);
EDIT : Another problem in your code while assigning next field.
node node1 = {1, {{0,0}, {5,0}, {5,5}, {0,5}}, &next1};
should be
node node1 = {1, {{0,0}, {5,0}, {5,5}, {0,5}}, (struct Node*)next1};
Here is the working code
#include<stdio.h>
typedef struct Position2D{
int x;
int y;
} position2D;
typedef struct Node{
int num;
position2D vertices[4];
struct Node *next;
} node;
/*traverse all nodes and their inner vertices arrays: */
void function(void){
/* initialisation: */
node *next1 = NULL;
node node1 = {1, {{0,0}, {5,0}, {5,5}, {0,5}}, (struct Node*)next1};
node *next0 = &node1;
node node0 = {0, {{0,10}, {10,10}, {10,15}, {0,15}}, (struct Node*)next0};
node *start = &node0;
node *p = NULL ;
int i=0;
for(p=start;p!=NULL;p=p->next) {
for (i=0; i<4; i++){ //traverse their four points
printf("%d %d \n",p->vertices[i].x, p->vertices[i].y);
}
}
}
int main() {
function();
return 0;
}

Related

no effect happening to the program when i am putting r=NULL in function ins()

While working with the pointers we are working on address, right?
So when a struct node pointer n is passed to t(struct node *t=n) and later if t is assigned NULL shouldn't n also become NULL?
ps-: it's a program of a binary tree
#include<stdio.h> //check at third line of ins() function
#include<stdlib.h>
struct node{
int data;
struct node* left,*right;
};
struct node* n(int dat){
struct node *x=(struct node*)malloc(sizeof(struct node));
x->data=dat;
x->left=NULL; x->right=NULL;
return x;
};
void ins(struct node* n,struct node* r){
struct node* t=r,*y=NULL; //ok so when i put r=NULL in this next line should this block of memory go
//r=NULL; //NULL
while(t!=NULL){
y=t;
if(t->data>n->data)
{
if(t->left==NULL)
{t->left=n;
t=NULL;
}
else
t=t->left;
}
else {
if(t->right==NULL){
t->right=n;
t=NULL;
}else
t=t->right;
}
}
}
void inorder(struct node* n){
if(n!=NULL){
inorder(n->left);
printf("%d ",n->data);
inorder(n->right);
}}
void main(){
struct node *a,*b,*c,*d,*e,*f,*g,*h;
a=n(32); b=n(20); c=n(100); d=n(16);
e=n(25); f=n(50); g=n(144); h=n(19);
a->left=b; a->right=c;
b->left=d; b->right=e;
c->left=f; c->right=g;
ins(h,a);
inorder(a);
}```
With struct node* t=r you are creating a new and independent variable t that points to the same location as r (lets call that A).
This means any changes to *r are reflected in *t as they both point to the same location A.
when assigning NULL to r, the t variable still points to location A, but r no longer does.
A small example:
int A = 0;
int *r = &A;
int *t = r;
// *r==0, *t==0, point to same location
*r = 55;
// *r==55, *t==55 (same location)
r = NULL;
// *t==55 (*r is no longer valid as r is NULL)

Printing a double pointer to a linked list in C [duplicate]

I have this code:
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
void pointerOfPointer(struct node **reference)
{
struct node *temporary = malloc(sizeof(struct node));
temporary->data = 100;
temporary->next = 0;
printf("before: temporary->data %d\n", temporary->data);
temporary = *reference;
printf("after: temporary->data %d\n", temporary->data);
}
int main()
{
struct node *linkedlist = malloc(sizeof(struct node));
linkedlist->data = 15;
linkedlist->next = 0;
pointerOfPointer(&linkedlist);
return 0;
}
How can I access the pointer to pointer of struct in the pointerOfPointer function without copying the *reference address to the temporary local variable? So in the end I can access the reference variable data using operator -> directly, like reference->data?
Remember that foo->bar is just syntactic sugar for (*foo).bar. What you're asking for is essentially (**reference).data, which you can rewrite as (*reference)->data if you want.

How to implement this create function correctly?

I'm trying to make a function to make a priority queue. My structs are this:
struct node {
char *item;
struct node *next;
};
struct queue {
struct node *start;
struct node *end;
};
struct priority_queue {
struct queue **aoq;
int x;
};
My function that I want to implement is:
struct priority_queue *priority_queue_create(int x);
Here, as seen in the structure priority_queue, struct queue **aoq is essentially an array of queues, which is want I want. int x, as in the function header, is the number of queues in the array.
My take on it is this:
struct priority_queue *priority_queue_create(int x) {
struct priority_queue *pq = malloc(sizeof(struct priority_queue));
pq->x = x;
pq->aoq = malloc(x* sizeof(struct queue));
return pq;
}
Where I put the 3 comment lines in the code above is where I suspect my error to be. I want to be able to do something like: if x = 3, there should be an array with 3 queues in it, and I suppose I'll be able to access it by doing something like
pq->aoq[0] /// to access the first queue in the array, or
pq->aoq[2] /// to access the third queue in the array
Can anyone help my fix my implementation? Thanks in advance.
Edit:
Other implementation I've tried:
struct priority_queue *priority_queue_create(int x) {
struct priority_queue *pq = malloc(sizeof(struct priority_queue *));
pq->x = x;
pq->aoq = malloc(x * sizeof(struct queue *));
for (int i = 0; i < x; ++i) {
pq->aoq[i] = malloc(sizeof(struct queue));
}
return pq;
}
From the code that you posted, I think this is the functionality that you want. You were missing the allocation of memory for the queues inside struct priority_queue, that is:
pq-> aoq = malloc( x * sizeof(struct queue *));
Adding this and keeping what you already had (with a sample main function to test the function priority_queue_create()), we have the following code:
#include <stdio.h>
#include <stdlib.h>
struct node {
char *item;
struct node *next;
};
struct queue {
struct node *start;
struct node *end;
};
struct priority_queue {
struct queue **aoq;
int x;
};
struct priority_queue *priority_queue_create(int x) {
struct priority_queue *pq = malloc(sizeof(struct priority_queue *));
pq->x = x;
pq-> aoq = malloc( x * sizeof(struct queue *));
for (int i = 0; i < x; ++i) {
pq->aoq[i] = malloc(sizeof(struct queue)); ///
}
return pq;
}
int main(){
struct priority_queue * pq = priority_queue_create(3);
char * str1 = "abcd";
char * str2 = "abcde";
pq->aoq[0]->start = malloc(sizeof(struct node));
pq->aoq[2]->start = malloc(sizeof(struct node));
pq->aoq[0]->start->item = str1;
pq->aoq[2]->start->item = str2;
printf("%s - %s\n", pq->aoq[0]->start->item, pq->aoq[2]->start->item);
free(pq->aoq[0]->start);
free(pq->aoq[2]->start);
free(pq->aoq[0]);
free(pq->aoq[1]);
free(pq->aoq[2]);
free(pq->aoq);
free(pq);
}

Generic Linked List in C

I have a linked_list struct:
typedef struct linked_list{
void *data;
struct linked_list *next;
struct linked_list *previous;
} linked_list;
And some linked list operations:
linked_list *init_linked_list() {
linked_list *ll;
ll = (linked_list *) malloc(sizeof(linked_list));
ll->next = ll;
ll->previous = ll;
return ll;
}
void add_element( linked_list *list, void *element) {
linked_list *list_element;
list_element = malloc(sizeof(linked_list));
list_element->data = element;
list_element->next = list->next;
list->next->previous = list_element ;
list->next = list_element ;
list_element->previous = list;
}
I have a graph struct:
typedef struct graph {
int number_vertices;
vertex **vertices;
} graph;
I have a vertex struct:
typedef struct vertex {
int time;
char *name;
linked_list *edges;
} vertex;
I have a edge struct:
typedef struct edge{
int weight;
int change;
vertex *to;
} edge;
And an "add-edge" function:
void add_edge_to_vertex(vertex *v, int weight, int change, vertex *to) {
edge *pEdge = malloc(sizeof(edge));
pEdge->weight = weight;
pEdge->change = change;
pEdge->to = to;
// add edge to vertex linked list
add_element(v->edges, pEdge);
}
Now to my problem. I setup my graph:
int aSize = 30;
int bSize = 30;
pGraph = malloc(sizeof(graph));
pGraph->vertices = malloc(sizeof(vertex*) * aSize);
pGraph->vertices[0] = malloc(sizeof(vertex) * bSize);
I setup my a vertex and init the linked_list:
vertex *pVertex ;
pVertex = malloc(sizeof(vertex));
pVertex->edges = init_linked_list();
And I add the vertex to my graph:
pGraph->vertices[a][b] = *pVertex;
Last I add an edge between two vertices:
add_edge_to_vertex(&pGraph->vertices[a][i], 100, 0, &pGraph->vertices[a][i+1]);
When I try to fetch the edge weight, I get an segment fault: 11
vertex *v = &pGraph->vertices[0][0];
linked_list *ll = v->edges;
int s = linked_list_size(ll);
printf("%d\n", s); // outputs 1 - works so far!
edge *e = (edge *) ll->data;
int weight = e->weight; // segment fault: 11 ..
I have also tried to add an int and a char to the linked_list struct, and fetched that value, instead of fetching (and casting) edge from the "void *data". This works.
My problem now is, that I don't know if my fault is when I fetch the data, or when I store the data.
Your linked list has one extra node at the start that does not have its data member initialized (the node created by the init_linked_list() function).
When you do :
edge *e = (edge *) ll->data;
you get that first node's data member, which is uninitialized. That causes the segmentation fault when you try to dereference e.
Try this instead :
edge *e = (edge *) ll->next->data;
which will get the data member for the node that was inserted by the last add_element function call. Obviously, this is only safe if there has been at least one element added into the linked list.

How to access an element of an array just given a pointer

struct node
{
int a;
node * link;
}
i have an array A with each element of type 'pointer to node' and hence each element of A can have variable size.Example
A[0]=NULL
A[1]=2->3->4
A[2]=3->4
and so on..
so to dynamically allocate an array if I use
u = (struct node*) malloc( m * sizeof(struct node*) )
then
u+i = NULL
(i is any integer) gives error as Lvalue required.
If I use array pointer as
struct node(*p)[];
and then use
(*p)+i = NULL
it gives error as L value required.
*(p+i) = NULL
gives error as
invalid use of array with unspecified bounds
What is the solution?
#include <stdio.h>
#include <stdlib.h>
typedef struct node node;
struct node{
int a;
node * link;
};
void print(node *np){
while(np){
printf("%d->", np->a);
np = np->link;
}
printf("NULL\n");
}
int main(){
struct node four = {4, NULL};
struct node three = {3, &four};
struct node two = {2, &three};
struct node **u;
int m = 3;
u = malloc(m * sizeof(struct node*));
u[0] = NULL;
u[1] = &two;
u[2] = &three;
for(int i=0;i<m;++i)
print(u[i]);
free(u);
return 0;
}
I think what you want is:
(*p) += i;
(*p) = NULL;
or
p[i] = NULL;
Here is a working example:
#include <stdio.h>
#include <string.h>
typedef struct s_node {
int x;
struct s_node *next;
} node ;
main()
{
node n[5];
n[2].x = 42;
printf("%d\n", n[2].x);
node *p = n;
printf("%d\n", p[2]);
p += 2;
printf("%d\n", p->x);
}
Output:
42
42
42
Consider to take a look at a tutorial for pointer arithmetic. Just google for it or click the provided link.

Resources