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