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;
}
Related
I have a list defined as
typedef struct node {
Voo *voo;
ListaReservas nodeReservas; /* Ignore this */
struct node *next;
} *Node;
I created some functions to help me add or remove nodes from the list like:
/* creates a node */
Node criaNode(Voo v) {
Node new = (Node)malloc(sizeof(struct node));
new->voo = &v;
/* I had new->voo = v; but vscode told me it was wrong so i changed it to &v */
new->next = NULL;
return new;
}
Voo is defined as:
typedef struct {
int dia;
int mes;
int ano;
} Data;
typedef struct {
int horas;
int minutos;
} Tempo;
typedef struct {
char codigo[LEN_CODIGO + 1];
char partidaID[LEN_ID + 1];
char chegadaID[LEN_ID + 1];
Data datapartida;
Tempo horapartida;
Tempo duracao;
Data datachegada;
Tempo horachegada;
int capacidade;
} Voo;
Now I wanted to iterate through the list and print its values as such
Voo *v;
for (n = headVoos; n != NULL; n = n->next) {
v = n->voo;
printf("%s %s %s %.2d-%.2d-%d %.2d:%.2d\n",
v->codigo, v->partidaID, v->chegadaID,
v->datapartida.dia, v->datapartida.mes, v->datapartida.ano,
v->horapartida.horas, v->horapartida.minutos);
}
The program is not printing correctly. For example where it should appear
AA1 AAA AAD 16-03-2022 14:50
its appearing instead
� 146187376-32765--1940381952 40355300:50
What's causing this and how can I avoid it in the future?
EDIT
After replacing in the struct node the Voo *voo definition by Voo voo, I am now getting an error in one of the auxiliary functions:
/* deletes node */
Node eliminaNode(Node head, Voo v)
{
Node n, prev;
for (n = head, prev = NULL; n != NULL; prev = n, n = n->next)
{
if (n->voo == v) /* expression must have arithmetic or pointer error */
{
if (n == head)
head = n->next;
else
prev->next = n->next;
free(n->next);
free(n);
break;
}
}
return head;
}
In criaNode you're taking the address of the parameter v and returning it from the function via a pointer to dynamic memory. That address is no longer valid after the function returns. Subsequently dereferencing that invalid address then triggers undefined behavior.
It probably makes more sense for struct node to contain a Voo directly instead of a pointer to one. So change the member to a non-pointer:
Voo voo;
And assign the parameter directly:
new->voo = v;
There are multiple problems here:
there seems to be a confusion between structures and pointers to structures. In C, you must understand the difference between manipulating objects (allocating as local objects or from the head, passing as arguments or returning as values) and pointers to objects, which are a more idiomatic as arguments to functions and allow functions to modify the object they point to.
the confusion is amplified by a very error prone construction: hiding pointers behind typedefs. Do not do that, define object types for the actual structure, using the same or a different name as the struct tag, and make all pointers explicit with the * syntax.
you pass an actual Voo object as an argument and allocate a list node using the address of this argument. This is incorrect because the argument will be discarded as soon as the function returns, makeing the list point to invalid memory and explaining the weird output you observe.
Node eliminaNode(Node head, Voo v) should take a pointer to the head node and return a success indicator. It should take a Voo * argument and it should not free(n->next) because the next node is still in use after the removal.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#define LEN_CODIGO 30
#define LEN_ID 30
typedef struct Data {
int dia;
int mes;
int ano;
} Data;
typedef struct Tempo {
int horas;
int minutos;
} Tempo;
typedef struct Voo {
char codigo[LEN_CODIGO+ 1];
char partidaID[LEN_ID + 1];
char chegadaID[LEN_ID + 1];
Data datapartida;
Tempo horapartida;
Tempo duracao;
Data datachegada;
Tempo horachegada;
int capacidade;
} Voo;
typedef struct Node {
struct Voo *voo;
//ListaReservas nodeReservas; /* Ignore this */
struct Node *next;
} Node;
/* creates a node */
Node *criaNode(Voo *v) {
/* allocation with calloc is safer as the object will be initialized to 0 */
Node *nodep = calloc(1, sizeof(*new));
if (nodep) {
nodep->voo = v;
nodep->next = NULL;
}
return nodep;
}
/* deletes node */
int eliminaNode(Node **head, Voo *v) {
for (Node *n = *head, *prev = NULL; n != NULL; prev = n, n = n->next) {
if (n->voo == v) {
if (n == *head)
*head = n->next;
else
prev->next = n->next;
free(n);
return 1; /* article was found and freed */
}
}
return 0; /* article was not found */
}
void printList(const Node *head) {
for (const Node *n = head; n != NULL; n = n->next) {
const Voo *v = n->voo;
printf("%s %s %s %.2d-%.2d-%.2d %.2d:%.2d\n",
v->codigo, v->partidaID, v->chegadaID,
v->datapartida.dia, v->datapartida.mes, v->datapartida.ano,
v->horapartida.horas, v->horapartida.minutos);
}
}
I have create two struct and two variables n1 and n2, here is the result when runnig code below:
10-nick-90.500000
20-wilson-100.500000.
What I want:
1.take elemtype variable values and put them into struct LNODE.
2.print values by using printlist(LNDOE* head).
Please help me.
#include <stdio.h>
#include <stdlib.h>
typedef struct elemtype{
int no;
char* name;
double score;
}elemtype;
typedef struct tagnode{
elemtype data;
struct tagnode* next;
}LNODE;
elemtype* print_elemtype(elemtype* data_to_print){
elemtype* p = data_to_print;
if ( p != NULL){
printf("%d-%s-%lf", p->no,p->name,p->score);
}
printf("\n");
return NULL;
}
void creat_link(LNODE** head, int n, void (*input)(elemtype*)){
LNODE* s;
*head = (LNODE*)malloc(sizeof(LNODE));
(*head)->next = NULL;
for(;n>0;n--){
s = (LNODE*)malloc(sizeof(LNODE));
input(&(s->data));
s->next = (*head)->next;
(*head)->next = s;
}
}
int main()
{
elemtype* n1 = malloc(sizeof(elemtype));
elemtype* n2 = malloc(sizeof(elemtype));
n1->name = "nick";
n1->no = 10;
n1->score = 90.5;
n2->name = "wilson";
n2->no = 20;
n2->score = 100.5;
elemtype** s1,**s2;
s1 = &n1;
s2 = &n2;
print_elemtype(n1);
print_elemtype(n2);
free(n1);
free(n2);
n1 = NULL;
n2 = NULL;
}
Crawl in your linked list with kind of code like this :
int main(void)
{
struct_type *list = allocat_struct_type();
struct_type *list_copy = list; // always copy the head of the list when your manipulating the list
while (list_copy != NULL) {
printf("%s", list_copy->text_to_display); // text_to_display must be an str type in this exemple
list_copy = list_copy->next;
}
}
if your still having problem precise where and when.
Feel free to ask me again i hope it help you i tried to understand what you would know but it's very blurry.
#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.
The problem is somewhere in here....
char buffer[80];
char *name;
while (1) {
fgets(buffer, 80, inf); //reads in at most 80 char from a line
if (feof(inf)) //this checks to see if the special EOF was read
break; //if so, break out of while and continue with your main
name = (char *) malloc(sizeof(char)*20);
....
name = strtok(buffer, " ");//get first token up to space
stock = newStock(name,...)
....
}
I'm working in C with generic linked lists. I made a list implementation that I've tested and know works with chars. I'm trying to add stocks (I created a stock struct) to the linked list, with each node of the linked list holding a stock struct, but when I finish reading in the stocks all of the nodes point to the same struct and I can't figure out why. Here's some snippets of my code
list *list = malloc(sizeof(list));
newList(list, sizeof(stock_t));
while(1) {
...
(read from file)
...
stock_t *stock;
stock = newStock(name, closes, opens, numshares, getPriceF, getTotalDollarAmountF,getPercentChangeF,toStringF);
addToBack(list, stock);
}
Here's the newStock function:
stock_t *newStock(char *name, float closingSharePrice, float openingSharePrice, int numberOfShares, getPrice getP, getTotalDollarAmount getTotal, getPercentChange getPercent, toString toStr) {
stock_t *stock = malloc(sizeof(stock));
stock->stockSymbol = name;
stock->closingSharePrice = closingSharePrice;
stock->openingSharePrice = openingSharePrice;
stock->numberOfShares = numberOfShares;
stock->getP = getP;
stock->getTotal = getTotal;
stock->getPercent = getPercent;
stock->toStr = toStr;
return stock;
}
In a way I see what's wrong. newStock returns a new pointer every time, but it always gets stored in the variable 'stock' which is what every node points to, so it's going to be equal to whatever the last pointer newStock returned was...but I don't see the way around this. I tried having newStock return just a stock_t, and doing addToBack(list, &stock), but that didn't solve the problem either.
Any help would be appreciated!
Here is some code from the list:
typedef struct node {
void *data;
struct node *next;
}node_t;
typedef struct {
int length;
int elementSize;
node_t *head;
node_t *tail;
} list;
void newList(list *list, int elementSize) {
assert(elementSize > 0);
list->length = 0;
list->elementSize = elementSize;
list->head = list->tail = NULL;
}
void addToBack(list *list, void *element) {
node_t *node = malloc(sizeof(node_t));
node->data = malloc(list->elementSize);
node->next = NULL; //back node
memcpy(node->data, element, list->elementSize);
if (list->length == 0) { //if first node added
list->head = list->tail = node;
}
else {
list->tail->next = node;
list->tail = node;
}
list->length++;
}
Here's code from the stock struct:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef float (*getPrice)(void *S);
typedef float (*getTotalDollarAmount)(void *S);
typedef float (*getPercentChange)(void *S);
typedef char *(*toString)(void *S);
typedef struct stock{
char *stockSymbol;
float closingSharePrice;
float openingSharePrice;
int numberOfShares;
getPrice getP;
getTotalDollarAmount getTotal;
getPercentChange getPercent;
toString toStr;
}stock_t;
The generic functions probably seem like overkill but this is for homework (if you couldn't tell already) so we were asked to specifically use them. I don't think that has anything to do with the problem though.
Here are the definitions for those functions anyway
float getPriceF(void *S) {
stock_t *stock = (stock_t*)S;
return stock->closingSharePrice;
}
float getTotalDollarAmountF(void *S) {
stock_t *stock = (stock_t*)S;
return ((stock->closingSharePrice) * (stock->numberOfShares));
}
float getPercentChangeF(void *S) {
stock_t *stock = (stock_t*)S;
return ((stock->closingSharePrice - stock->openingSharePrice)/(stock->openingSharePrice));
}
char *toStringF(void *S) {
stock_t* stock = (stock_t*)S;
char *name = malloc(20*sizeof(char));
//sprintf(name, "Symbol is: %s. ", (stock->stockSymbol));
return stock->stockSymbol;
}
void printStock(void *S) {
char *str = toStringF(S);
printf("%s \n", str);
}
And this is how I'm traversing the list:
typedef void (*iterate)(void *); //this is in the list.h file, just putting it here to avoid confusion
void traverse(list *list, iterate iterator) {
assert(iterator != NULL);
node_t *current = list->head;
while (current != NULL) {
iterator(current->data);
current = current->next;
}
}
And then in my main I just called
traverse(list, printStock);
I can't find any problems with your code (that would cause your problem, anyway - there are places where you don't check the return from malloc() and stuff like that, but those are not relevant to this question). You don't supply the definition of stock_t, so I made a new data struct, and a new couple of functions, otherwise I just copied and pasted the code you provided:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* Your code starts here */
typedef struct node {
void *data;
struct node *next;
}node_t;
typedef struct {
int length;
int elementSize;
node_t *head;
node_t *tail;
} list;
void newList(list *list, int elementSize) {
assert(elementSize > 0);
list->length = 0;
list->elementSize = elementSize;
list->head = list->tail = NULL;
}
void addToBack(list *list, void *element) {
node_t *node = malloc(sizeof(node_t));
node->data = malloc(list->elementSize);
node->next = NULL; //back node
memcpy(node->data, element, list->elementSize);
if (list->length == 0) { //if first node added
list->head = list->tail = node;
}
else {
list->tail->next = node;
list->tail = node;
}
list->length++;
}
/* Your code ends here */
/* I made a new struct, rather than stock, since you didn't supply it */
struct mydata {
int num1;
int num2;
};
/* I use this instead of newStock(), but it works the same way */
struct mydata * newNode(const int a, const int b) {
struct mydata * newdata = malloc(sizeof *newdata);
if ( newdata == NULL ) {
fputs("Error allocating memory", stderr);
exit(EXIT_FAILURE);
}
newdata->num1 = a;
newdata->num2 = b;
return newdata;
}
/* I added this function to check the list is good */
void printList(list * list) {
struct node * node = list->head;
int n = 1;
while ( node ) {
struct mydata * data = node->data;
printf("%d: %d %d\n", n++, data->num1, data->num2);
node = node->next;
}
}
/* Main function */
int main(void) {
list *list = malloc(sizeof(list));
newList(list, sizeof(struct mydata));
struct mydata * data;
data = newNode(1, 2);
addToBack(list, data);
data = newNode(3, 4);
addToBack(list, data);
data = newNode(5, 6);
addToBack(list, data);
printList(list);
return 0;
}
which outputs this:
paul#MacBook:~/Documents/src$ ./list
1: 1 2
2: 3 4
3: 5 6
paul#MacBook:~/Documents/src$
demonstrating that you have a 3 node list, with all nodes different and where you'd expect them to be.
Either there is some other problem in code you're not showing, or for some reason you are thinking each node points to the same struct when it actually doesn't.
One possibility is that you have a char * data member in your stock struct. It's impossible to tell from the code you provided, but it's possible that you really are creating different nodes, but they all end up pointing to the same name, so they just look like they're the same. If you're assigning a pointer to name, you should make sure it's freshly allocated memory each time, and that you're not just, for instance, strcpy()ing into the same memory and assigning the same address to each stock struct.
EDIT: Looks like that was your problem. This:
name = (char *) malloc(sizeof(char)*20);
....
name = strtok(buffer, " ");
should be:
name = (char *) malloc(sizeof(char)*20);
....
strcpy(name, strtok(buffer, " "));
Right now, you malloc() new memory and store a reference to it in name, but then you lose that reference and your memory when you overwrite it with the address returned from strtok(). Instead, you need to copy that token into your newly allocated memory, as shown.
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.