realloc two dimensional struct array - c

#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.

Related

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

C - Not working (node) structures in main function (intentionally avoiding use of singly linked list implementation)

I'm trying to create a singly linked list without implementation. I'm doing this just to gain some deeper understanding on how structures work. I just want to create 2 nodes in the main function and link them. I could do that using typedef in the declaration of structures and by making the implementation, but that's not what I want (I can do that successfully).
I've written some code, but an error occurs at line 27 (the same problem appears at lines 29, 30 and 33). I know the explanation for this problem is rather simple, but I couldn't find it, either on my mind or on the web (or books). I'd appreciate any assistance in this problem. I've been programming just for the last year.
I thought in asking for help in CodeReview, but accordingly, to their FAQ, that wasn't the place to ask for help with this kind of problem.
Errors are:
27:11: error: incompatible types when assigning to type 'struct NODO ' from type 'struct NODO'
E.sig = F;
Same problem with the other lines. Everything is in the same file (.c).
Here's the full code:
#include <stdio.h>
#include <stdlib.h>
struct NODE {
int data;
struct NODE *next;
};
struct LIST {
struct NODE *first;
struct NODE *last;
int size;
};
void main(){
struct NODE E;
struct NODE F;
struct LIST L;
E.data = 1;
E.next = NULL;
F.data = 2;
F.next = NULL;
E.next = F; // line 27
L.first = E; // line 29
L.last = F; // line 30
struct NODE *ptr;
ptr = E; // line 33
while(ptr != NULL){
printf("%i\n", ptr->data);
ptr = ptr->next;
}
}
The problem is that you are trying to assign an object to a pointer. You should assign the address of your node and note the node object itself.
Try E.next = &F; and same for all the others.
A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. So you have to provide the address of the memory location .In C address of a variable is derived using & operator.
Modified code :-
#include <stdio.h>
#include <stdlib.h>
struct NODE {
int data;
struct NODE *next;
};
struct LIST {
struct NODE *first;
struct NODE *last;
int size;
};
int main(){
struct NODE E;
struct NODE F;
struct LIST L;
E.data = 1;
E.next = NULL;
F.data = 2;
F.next = NULL;
E.next = &F; // not E.next = F;
L.first = &E; // not L.first = E;
L.last = &F; // not L.last = F;
struct NODE *ptr;
ptr = &E; // not ptr = E;
while(ptr != NULL){
printf("%i\n", ptr->data);
ptr = ptr->next;
}
return 0;
}
Recommended to use int main() instead of void main().
Output :-
1
2
I've found the solution or at least some additional information that led me towards the solution minutes after sending the question to SO.
In Wikipedia (https://en.wikipedia.org/wiki/Struct_(C_programming_language)#Pointers_to_struct) I've found the next snippet of code:
struct point {
int x;
int y;
};
struct point my_point = { 3, 7 };
struct point *p = &my_point; /* To declare and define p as a pointer of type struct point,
and initialize it with the address of my_point. */
My mistake was using the pointer to point to the structure and not to the structure's address. Pointers can point only to addresses (they store its value), they cannot point to objects.

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

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.

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