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

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.

Related

Accessing a struct within array within a struct

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

realloc two dimensional struct array

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct a // linked list node
{
char* st;
struct a* pr;
struct a* nx;
};
struct a* Init(char* w);
struct a* insert(struct a* old, char* w);
int main(void)
{
struct a** A;
A = (struct a**)malloc(sizeof(struct a*));
A[0] = Init("HELLO");
A[0] = insert(A[0], "WORLD");
// I think the problem is here.
A = (struct a**)realloc(A, 2*sizeof(struct a*));
A[1] = Init("ELLO");
A[1] = insert(A[1], "ORLD");
free(A);
return 0;
}
struct a* Init(char* w)
{
struct a* body = (struct a*)malloc(sizeof(struct a));
struct a* tail = (struct a*)malloc(sizeof(struct a));
body -> pr = NULL;
body -> nx = tail;
body -> st = w;
tail -> pr = body;
tail -> nx = NULL;
tail -> st = NULL;
return tail;
}
struct a* insert(struct a* old, char* w)
{
struct a* tail = (struct a*)malloc(sizeof(struct a*));
old -> nx = tail;
old -> st = w;
tail -> pr = old;
tail -> nx = NULL;
tail -> st = NULL;
return tail;
}
(I abridged my code)
I constructed two dimensional structure array, but this code keeps giving me an error, segmentation fault.
I think the problem is here.
A = (struct a**)realloc(A, 2*sizeof(struct a*));
But I have no idea why it is wrong.
Is there any idea?
Thanks in advance!.
In insert() function, you allocated room for only one pointer by this line
struct a* tail = (struct a*)malloc(sizeof(struct a*));
On the other hand, struct a has three pointers, so its size will be larger than size of one pointer in typical environment.
Therefore, some out-of-range access will happen. Try allocating sizeof(struct a) as you did in Init() function.

create new nodes that point at each other

struct x{
...;
...;
struct x * next;
};
struct x create() {
struct x new = malloc...
new->... = .;
new->... = ..;
new->next = NULL
};
When i create a new node of struct x how does it work when using struct x create multiple times. It feels strange for me that you can use it multiple times because It allocate memory to a struct x with the same name new each time? Doesn't each node of a struct require an individual name. Or Does it only matters that each time a new memory allocation is done.
Main problem: I will create first node and then a second node. The first node should then point at the second node and so on. But when I create the first node the second doesn't exists so I can't set first->next = second.
I have looked at linked lists examples but it doesn't improve my thinking at the moment. The code isn't that important as my own understanding and thinking. Please help me think and grasp the concept.
//I tried to follow the sugestions from Degustaf(except the next pointer, basically the same as create a new node) but did the implementation wrong. So I wounder whats wrong with this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct x{
int a;
int b;
struct x * next;
}
struct x *create(int a , int b){
struct x *new = malloc(sizeof(struct x));
new->a = a;//namn skitsamma allokering relevant
new->b = b;
new->next = NULL;
return new;
};
int main() {
struct x *x1 = struct x *create(12,13);
return 0;
}
You can simply assign the values of the pointers after you've created both.
i.e.,
struct x x1 = create();
struct x x2 = create();
x1.next = &x2;
x2.next = &x1;
Or Does it only matters that each time a new memory allocation is done.
Correct.
But, there are other issues with your code. In particular, you aren't returning anything from your create function. I see 2 ways to approach this to remedy the problem. The first is that you can return the struct directly, which means that you don't need the malloc:
struct x create()
{
struct x new;
new.member1 = .;
new.member2 = ..;
new.next = NULL;
return new;
};
Then you can populate it using
struct x x1 = create();
struct x x2 = create();
x1.next = &x2;
The other possibility is to return a pointer to a struct, in which case this becomes
struct x *create()
{
struct x *new = malloc...;
new->member1 = .;
new->member2 = ..;
new->next = NULL;
return new;
};
Then you can populate it using
struct x *x1 = create();
x1->next = create();
My opinion is that the second option is cleaner as you don't need to worry about individual elements of your linked list going out of scope, although it does require being careful when it comes to freeing memory (needing to traverse the list and free one element at a time.
I thing this is what you want but this is a example with intenger numbers in a list also yoy can change the code as you wish.
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <iostream>
struct cell {
float info;
struct cell * next;
};
int more (float * k)
{
char ans[4];
printf("Continue Yes/No: ");
scanf("%s",ans);
if (ans[0]=='Y') {
printf("insert value: ");
scanf("%f",k);
return(1);
}
else
return(0);
}
struct cell * crelist()
{
struct cell * last = (struct cell *)NULL;
struct cell * ptr = (struct cell *)NULL;
struct cell * list = (struct cell *)NULL;
float k;
ptr = (struct cell *)malloc(sizeof(struct cell));
if (ptr != (struct cell *)NULL) {
printf("insert value: ");
scanf("%f",&k);
ptr->info = k;
ptr->next = (struct cell *)NULL;
list = ptr;
last = ptr;
}
else
return((struct cell *)NULL);
while (more(&k)) {
ptr = (struct cell *)malloc(sizeof(struct cell));
if (ptr != (struct cell *)NULL) {
ptr->info = k;
ptr->next = (struct cell *)NULL;
last->next = ptr;
last = ptr;
}
else
break;
}
return(list);
}
void printlist(struct cell * list)
{
struct cell * p;
p = list;
while (p != (struct cell *)NULL) {
printf("->%f\n",(*p).info);
p=(*p).next;
}
return;
}
int main()
{
struct cell * list;
int i;
list = crelist();
printlist(list);
scanf("%d",&i);
system("pause");
return 0;
}

Error in simple linked list code

I try to create a simple linked list out of a integer vector. Why is this not working? The errors I get are:
'=' : incompatible types - from 'talstrul *' to 'node *'
'=' : cannot convert from 'talstrul*' to talstrul'
This is the .h file:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int num;
struct node *next;
} talstrul;
This is the .c file:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "clabb2head.h"
int main()
{ int vek[5] = {1,2,3,4,5};
int langd = sizeof(vek)/sizeof(vek[0]);
printf("%d",langd);
talstrul *temp = malloc(sizeof(talstrul));
talstrul *pek1 = NULL;
int i;
for(i=0; i<langd; i++)
{
pek1 -> num = vek[i];
pek1 -> next = *temp;
*temp = pek1;
}
}
temp is of type talstrul *
talstrul *temp = malloc(sizeof(talstrul));
You are trying to assign to next, which is of type node *
struct node *next;
Further
pek1 -> next = *temp;
dereferences temp, yielding a talstrul. You should not dereference the pointer.
The compiler is giving you a pretty good explanation of what is going wrong.
Another problem with the code :
pek1 is assigned to NULL. Yet you try to assign pek1->num and pek1->next. You should do memory allocation for pek1 first.
typedef struct node {
int num;
struct node *next;
} talstrul;
...
int vek[5] = {1,2,3,4,5};
int langd = sizeof(vek)/sizeof(vek[0]);
talstrul *pek1 = NULL;
int i;
for(i=0; i<langd; i++){
talstrul *temp = malloc(sizeof(talstrul));
temp -> num = vek[i];
temp -> next = pek1;
pek1 = temp;
}

C LinkedList example doesn't compile

The following C code is my own way of writing a primitive linked list. It uses a struct called lnode. I know this is not the best/most efficient way to do it but my idea is this: create the base node, use an "iterator" pointer, here q, that points to that last node in the list and then add a new node.
The following code will not compile. I can't find the cause but it hates this line
struct lnode *q= malloc(sizeof(struct lnode));
Any advice on making this idea work? Thanks in advance.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
struct lnode{
int value;
struct lnode *nextnode;
};
int main(){
struct lnode *startnode = malloc(sizeof(struct lnode));
startnode->value=0;
startnode->nextnode=NULL;
struct lnode *q= malloc(sizeof(struct lnode));
int i = 0;
for(i=0;i<10;i++){
struct lnode *p = malloc(sizeof(struct lnode));
p= q->nextnode;
p->value=i;
p->nextnode=NULL;
q=p;
}
return 0;
}
I would like to point out that I'm a novice. I'm using the Watcom compiler (Why? My computer is old and its all I need for these practice porgrams) The log output is
structure1.c(17): Error! E1063: Missing operand structure1.c(17):
Warning! W111: Meaningless use of an expression structure1.c(17):
Error! E1009: Expecting ';' but found 'struct' structure1.c(17):
Error! E1011: Symbol 'lnode' has not been declared structure1.c(17):
Error! E1011: Symbol 'q' has not been declared structure1.c(17):
Error! E1014: Left operand must be an 'lvalue' structure1.c(19):
I followed the advice given and changed the code the new code is this:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
struct lnode{
int value;
struct lnode *nextnode;
};
int main(){
struct lnode *startnode = (struct lnode *)malloc(sizeof(struct lnode));
struct lnode *q;
startnode->value=0;
startnode->nextnode=NULL;
q = malloc(sizeof(struct lnode));
doLoop(q);
return 0;
}
void doLoop(struct lnode *q){
int i = 0;
for(i=0;i<10;i++){
struct lnode *p = (struct lnode *)malloc(sizeof(struct lnode));
q->nextnode=p;
p->value=i;
p->nextnode=NULL;
printf("%i, %i\n",p->value,q->value);
q=p;
}
}
I printed the "value" values of each node in the list along with the previous value. It works except the first iteration which gives a weird output.
I suspect the compiler (Microsoft compilers for example) supports C89 standard only, which does not permit the intermingling of code and declarations. Move declaration of q to top of scope:
int main(){
struct lnode *startnode = (struct lnode *)malloc(sizeof(struct lnode));
struct lnode *q
startnode->value=0;
startnode->nextnode=NULL;
q = malloc(sizeof(struct lnode));
The code compiles - http://ideone.com/j6fGe - but the logic is wrong:
struct lnode *p = (struct lnode *)malloc(sizeof(struct lnode));
p= q->nextnode;
Besides the fact that you have a memory leak, I'm sure this is not what you intended.
q->nextnode doesn't point to a valid node, just some random memory. Which you then try to overwrite with p->value=i;.
The error messages is due to the mixing of code and declarations.
Further; You switch p and q around in the for loop.
p = q->next_node; /* here you set p to an undefined area.
* q->next_node is not malloc'd */
p->value = i; /* here you cause undefined / erronous behaviour
* Most probably a SIGSEGV */
So to sum it up, perhaps something like:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
struct lnode{
int value;
struct lnode *nextnode;
};
int main(void)
{
struct lnode *startnode;
struct lnode *p;
size_t z;
int i;
z = sizeof(struct lnode);
if ((startnode = malloc(z)) == NULL) {
fprintf(stderr, "Unable to malloc %d bytes.\n", z);
return 1;
}
/* Fill list */
p = startnode;
for (i = 0; i < 10; i++) {
if ((p->nextnode = malloc(z)) == NULL) {
fprintf(stderr, "Unable to malloc %d bytes.\n", z);
return 1;
}
p->value = i;
p = p->nextnode;
p->nextnode = NULL;
}
/* Print values */
p = startnode;
while (p->nextnode != NULL) {
printf("value: %2d\n", p->value);
p = p->nextnode;
}
/* Free */
p = startnode;
while (p != NULL) {
p = p->nextnode;
free(startnode);
startnode = p;
}
return 0;
}

Resources