Pointer to struct "undeclared (first use in this function)" - c

I'm trying to implement a linked list in C,
and i'm having a hard time figuring out why I'm getting the following error when compiling:
entryList.c:7:11: error: 'tmp' undeclared (first use in this function)
entry * tmp = NULL;
entryList.c:7:11: note: each undeclared identifier is reported only once for
each function it appears in
^
I already wrote a few linked lists for this program, they all use a similar syntax, but the compiler only complains about this one.
I have my struct definition in header.h:
/*definition of entry type*/
typedef struct entry
{
char * label;
short int address;
struct entry * next;
} entry;
and in entryList.c, I'm writing a function to add a node to the linked list.
#include "header.h"
static entry * head = NULL;
void addEntry(char * entry, int line)
{
entry * tmp = NULL;
char * label = NULL;
tmp = malloc(sizeof(entry));
label = malloc(sizeof(char)*MAX_LINE);
strcpy(tmp->label, entry);
tmp->address = 0;
tmp->next = NULL;
if (!head)
{
head = tmp;
}
else
{
entry * p = head;
while (p->next)
p = p->next;
p->next = tmp;
}
}

void addEntry(char * entry, int line)
{
entry * tmp = NULL;
You have both a parameter and a type named entry. Change one of them to something else.

Related

Code is printing pointer address (I think) instead of value?

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

Adding a node to the begining of a linked list results in error message I don't follow

I found relevant content about this in previous posts, but I get an error message when I try to compile the suggested code. As the subject suggests, I am trying to add a node to the beginning of a linked list. I posted the entire file to provide more context...
#include <stdio.h>
#include <stdlib.h>
struct entry {
int value;
struct entry *next;
};
struct entry *findEntry ( struct entry *listPtr, int match)
{
while ( listPtr != (struct entry *) 0)
{
printf ("Here is the current value%i\n", listPtr->value);
if ( listPtr->value == match )
return (listPtr);
else
listPtr = listPtr->next;
}
return (struct entry *) 0;
}
void insertEntry ( struct entry *newNode, struct entry *targetPtr)
// This function inserts a node after the targe Node
{
// set the pointer inside of new object to point to what target node is pointting to right now
newNode->next = targetPtr->next;
printf("Here is what is in new node value%i\n Here is what is in targetNode value %i\n",newNode->next, targetPtr->next);
// Now move the pointer inside of target node, and point to new object
targetPtr->next = newNode;
}
struct entry newNodef ()
{
struct entry node, *nodePtr;
int newValue;
printf("Please tell me what value you want to store in the new node\n");
scanf("%i", &newValue);
node.value = newValue;
return node;
}
void addFirst (struct entry **listStart, int value)
{
struct entry *new_entry = ( struct entry*) malloc (sizof (struct entry));
new_entry->value = value;
new_entry->next =*listStart;
*listStart = new_etnry;
}
int main (void)
{
struct entry *findEntry ( struct entry *listPtr, int match);
void addFirst (struct entry **listStart, int value);
void insertEntry ( struct entry *newNode, struct entry *targetPtr);
struct entry newNodef ();
struct entry n1, n2, n3;
struct entry *listPtr, *targetPtr, *listStart = &n1;
int search;
n1.value = 100;
n1.next = &n2;
n2.value = 200;
n2.next = &n3;
n3.value =300;
n3.next = (struct entry *) 0;
struct entry tempNode = newNodef();
listPtr = &tempNode;
targetPtr = &n2;
insertEntry ( listPtr, targetPtr);
printf("Here is what the new node is pointing to now %i. \n", tempNode.next->value );
printf ("Enter value to locate: ");
scanf ("%i", &search);
listPtr = findEntry (listStart, search);
if ( listPtr != (struct entry *) 0)
printf ("Found %i.\n", listPtr->value);
else
printf ("Not found. \n");
int v=700;
addFirst(&listStart, v);
return 0;
}
Here are the error messages...
$ make
gcc temp.c -o temp
temp.c: In function 'addFirst':
temp.c:42:61: error: expected expression before 'struct'
struct entry *new_entry = ( struct entry*) malloc (sizof (struct entry));
^
temp.c:45:16: error: 'new_etnry' undeclared (first use in this function)
*listStart = new_etnry;
^
temp.c:45:16: note: each undeclared identifier is reported only once for each function it appears in
make: *** [temp] Error 1
I basically followed the advice provided at the bottom of this post since I could understand his explanation. If there is a better way of doing this w/o using pointer to a pointer, please let advise.
Spelling mistake in sizof --> sizeof
Spelling mistake in new_etnry --> new_entry
In insertentry change the printf specifier to %p or change the arguments to newNode->value and targetPtr->value
Unused variable nodePtr in newNodef

insert sort with doubly linked list

I've been working on a set of functions for doubly linked lists, one that I've had trouble with is inserting elements into the list but keeping the list in sorted order. So if I have a list of {3, 4, 6} and insert 5 then the list will become {3, 4, 5, 6}
I just finished the latest code after rewriting it last night, please comment and tell me if there is a better way, I am posting both the header file and the c file. One thing I want to point out is that I do not use a pointer to the current node and only create one pointer in the insert function that creates a new node with a temp placement.
LIST.H
/* custom types */
typedef struct node
{
int val;
struct node * next;
struct node * prev;
}Node;
typedef struct list
{
Node * head;
Node * tail;
}List;
/* function prototypes */
/* operation: creates a list */
/* pre: set equal to a pointer to a list*/
/* post: list is initialized to empty */
List* NewList();
/* operation: Insert a number into a list sorted */
/* pre: plist points to a list, num is an int */
/* post: number inserted and the list is sorted */
void Insert(List * plist, int x);
LIST.C
/* c file for implentation of functions for the custome type list */
/* specifically made for dueling lists by, Ryan Foreman */
#include "List.h"
#include <stdlib.h> /* for exit and malloc */
#include <stdio.h>
List* NewList()
{
List * plist = (List *) malloc(sizeof(List));
plist->head = NULL;
plist->tail = NULL;
return plist;
}
void Insert(List * plist, int x)
{
/* create temp Node p then point to head to start traversing */
Node * p = (Node *) malloc(sizeof(Node));
p->val = x;
/* if the first element */
if ( plist->head == NULL) {
plist->head = p;
plist->tail = p;
}
/* if inserting into begining */
else if ( p->val < plist->head->val ) {
p->next = plist->head;
plist->head->prev = p;
plist->head = p;
}
else {
p->next = plist->head;
int found = 0;
/* find if there is a number bigger than passed val */
while((p->next != NULL) && ( found == 0)) {
if(p->val < p->next->val)
found = 1;
else {
p->next = p->next->next;
}
}
/* if in the middle of the list */
if(found == 1)
{
p->prev = p->next->prev;
p->next->prev = p;
}
/* if tail */
else {
plist->tail->next = p;
p->prev = plist->tail;
plist->tail = p;
}
}
}
Thank you for any input on the code, any comments are appreciated
Some comments on your C' utilisation.
In C, cast from pointer to void to pointer to object is unecessary.
It could be a good idea to check malloc return in such library.
malloc() does not zero memory, you don't set your first nodes next/prev, so your while loop could go on forever if second node >= first node value, ie exit condition p->next != NULL is not met.

linked list && structures

I would like to know if design of my program is correct, as well as to understand if my commented area is doing what it supposed to be doing. I get these compile errors that are associated probably with commented segments of my code, and I would lie to receive some help. THANKS!
part1.c:15:6: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'insert'
part1.c: In function 'main':
part1.c:43:14: error: incompatible types when assigning to type 'struct point' from type 'int'
part1.c:49:44: error: invalid type argument of '->' (have 'struct point')
part1.c:49:59: error: invalid type argument of '->' (have 'struct point')
part1.c:55:5: error: incompatible type for argument 1 of 'free'
/usr/include/stdlib.h:488:13: note: expected 'void *' but argument is of type 'struct point'
char *chars[3]= {"a","b","c"};
int nums[3]= {5,8,9};
struct point {char *letter;
int number;
struct point *next;};
struct point* insert(struct point list[],char *rqdLetters, int rqdNums)
{
struct point *new;
new = (struct point*)malloc(sizeof(struct point));
if(new == NULL)
fprintf(stderr,"error!");
new->letter = rqdLetters;
new->number = rqdNums;
new->next = head;
head = new;
//not sure if i'm returning the a pointer to the start of new list
return head;
}
int main(int argc, char **argv)
{
//not sure if i need to declare these here or in the insert
struct point list[3];
struct point *head = NULL;
struct point *next;
struct point *new;
int i;
for (i = 0; i < 3; i++)
{
//return result put back into the pointer to the start of the list
head[i] = insert(list[i], chars[i], nums[i]);
}
int j;
for(j = 0; j < 3; j++)
{
printf("letter %s and number %d\n", list[j]->letter, list[j]->number);
}
int z;
for(z = 0; z < 3; z++)
{
free(list[z]);
}
return 0;
}
At a glance, there are several issues with your code. Firstly, you're not declaring your variables correctly.
new = list;
should be:
struct point* new;
Your function signature also looks a little suspect. If you're returning a pointer to your data structure, it should be something like:
struct point* insert(...) { ... }
At a more general level, I does seem like your idea of a linked list may be a little off. To represent a list, you should only need to hold on to the head and tail of the list, instead of keep an array of your points.
It usually helps if you create a data structure to hold these pointers. You can then pass this structure around to functions that operate on the list e.g. the insert() function.
As a quick example (untested):
struct node {
struct node *next;
char letter;
int number;
}
struct list {
struct node *head;
struct node *tail;
}
/* create a new list */
struct list* list_new(void) {
struct list *L = malloc(sizeof(struct list));
L->head = NULL;
L->tail = NULL;
}
/* add a new node to the list */
void list_insert(struct list *list, char in_letter, int in_number) {
struct node *node = malloc(sizeof(struct node));
node->letter = in_letter;
node->number = in_number;
node->next = NULL;
if (list->head == NULL) { /* empty list */
list->head = node;
list->tail = node;
} else { /* append to list */
list->tail->next = node;
list->tail = node;
}
}
You can then use it as such:
int i;
char chars[3]= {"a","b","c"};
int nums[3]= {5,8,9};
struct list *mylist = list_new();
for (i = 0; i < 3; i++)
{
list_insert(mylist, chars[i], nums[i]);
}
In response to:
... and i am not sure if i am supposed to declare it inside insert or main, i did in the main however
This depends on where you intend to use the variables and the intended lifespan of these variables. As stated in the comments above, you might want to polish up on your understanding of scoping rules.

Compiling error for linked list in c

I did my whole project in NetBeans on my mac and it works fine. Then I go to put it into terminal to submit it on our ssh server for school and its giving me a bunch of compilation errors. Did netbeans compile in c++ or something? I'm new to c so any help is certainly appreciated. Here's the code.
/*
* File: LinkedList.c
* Author: dpiganell
*
* Created on October 17, 2011, 2:31 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct element{
int i;
struct element *next;
};
void insert(struct element**, struct element*);
void purge (struct element*, struct element*);
void printList(struct element*);
void printListBackwards(struct element*);
struct element *h;
int main()
{
// HEAD
h = (element *) malloc(sizeof(element));
h = NULL;
// NEW VALUE
struct element *n = NULL;
// POINTER TO THE POINTER OF HEAD
struct element **headPointer;
headPointer = (element **) malloc(sizeof(element));
int a;
a = 1;
while(a >= 0)
{
n = (element *) malloc(sizeof(element));
printf("\nPlease enter an integer value: ");
scanf("%d", &a);
if(a >= 0)
{
n->i = a;
n->next = NULL;
headPointer = &h;
insert(headPointer, n);
n = n++;
}
printList(h);
printListBackwards(h);
}
return 0;
}
void insert(struct element **head, struct element *n)
{
element *nptr, *pptr, *cptr;
// NEW POINTER, PREVIOUS POINTER, CURRENT POINTER
nptr = (element *) malloc(sizeof(element));
int purged;
purged = -1;
if(nptr != NULL)
{
nptr->i = n->i;
nptr->next = NULL;
cptr = *head;
pptr = NULL;
}
while(cptr != NULL && n->i >= cptr->i)
{
if(cptr->i == n->i && purged != 1)
{
purged = 1;
purge(cptr, pptr);
}
else
{
pptr = cptr;
cptr = cptr->next;
}
}
if(pptr == NULL && purged < 0)
{
nptr->next = *head;
*head = nptr;
}
else if(purged < 0)
{
pptr->next = nptr;
nptr->next = cptr;
}
}
void purge(struct element *current, struct element *predecessor)
{
element *ptr = (element *) malloc(sizeof(element));
// ERASING THE HEAD
if(predecessor == NULL)
{
if(current->next == NULL)
{
current->next = NULL;
current->i = NULL;
current = NULL;
free(current);
h = NULL;
}
else
memcpy(current, current->next, sizeof(element));
}
// ERASING THE TAIL
else if(current->next == NULL)
{
current->i = NULL;
free(current->next);
free(current);
predecessor->next = NULL;
}
// ERASING ANYTHING IN THE MIDDLE OF THE LIST
else
{
ptr = current->next;
predecessor->next = ptr;
current->i = NULL;
free(current->next);
}
}
void printList(struct element *head)
{
if(head == NULL)
printf("The list is empty.");
else
{
struct element *ptr;
ptr = (element*) malloc(sizeof(element));
ptr = head;
int a;
a = 1;
printf("Forwards: ");
while(a > 0)
{
printf("%d ", ptr->i);
if((ptr->next) == NULL)
a = -1;
else
ptr = ptr->next;
}
}
}
void printListBackwards(struct element *ptr)
{
if(ptr == NULL)
{
// DO NOTHING BECAUSE IT WILL BE PRINTED ALREADY THAT IT IS EMPTIED
}
else
{
element *cptr = (element *) malloc(sizeof(element));
cptr = ptr;
if(ptr->next == NULL)
printf("\nBackwards: %d ", ptr->i);
else
{
printListBackwards(ptr->next);
printf("%d ", ptr->i);
}
}
}
Also, here are the errors. It works fine and compiles fine in netbeans.
LinkedList.c:14: warning: useless keyword or type name in empty declaration
LinkedList.c: In function `main':
LinkedList.c:26: error: `element' undeclared (first use in this function)
LinkedList.c:26: error: (Each undeclared identifier is reported only once
LinkedList.c:26: error: for each function it appears in.)
LinkedList.c:26: error: syntax error before ')' token
LinkedList.c:34: error: syntax error before ')' token
LinkedList.c:40: error: syntax error before ')' token
LinkedList.c: In function `insert':
LinkedList.c:65: error: `element' undeclared (first use in this function)
LinkedList.c:65: error: `nptr' undeclared (first use in this function)
LinkedList.c:65: error: `pptr' undeclared (first use in this function)
LinkedList.c:65: error: `cptr' undeclared (first use in this function)
LinkedList.c:68: error: syntax error before ')' token
LinkedList.c: In function `purge':
LinkedList.c:110: error: `element' undeclared (first use in this function)
LinkedList.c:110: error: `ptr' undeclared (first use in this function)
LinkedList.c:110: error: syntax error before ')' token
LinkedList.c: In function `printList':
LinkedList.c:153: error: `element' undeclared (first use in this function)
LinkedList.c:153: error: syntax error before ')' token
LinkedList.c: In function `printListBackwards':
LinkedList.c:179: error: `element' undeclared (first use in this function)
LinkedList.c:179: error: `cptr' undeclared (first use in this function)
LinkedList.c:179: error: syntax error before ')' token
In C, this definition
struct element{
int i;
struct element *next;
};
has to be referred to as struct element. You get that right in some places, not all. A known idiom is:
typedef struct element {
int i;
struct element *next;
} element;
Which typedefs element as struct element so you don't need to place struct in front of the type. This was so common that C++ kind of "does this for you" so struct is no longer needed.
It's C, you cannot use bare element, it's struct element.
Your issues are related to how you declare your struct element vs. how you use it.
typedef struct element{
int i;
struct element *next;
} element;
will give you more satisfactory results.
Alternately, you can leave your struct as it is, wherever you use a bare element, instead write struct element.
BTW:
This isn't related to your exact problem, but I thought I would share (as my compiler gave me a warning about it); you sometimes write:
current->i = NULL;
In this case, i is an integer. In C, NULL is traditionally used only for pointer types. So as not to confuse, you should either change the assignment to:
current->i = 0;
...or, if i actually is meant to point to memory somewhere (which given the context above, I presume it is not), declare it as a pointer type.
You need to typedef your struct if you're going to use it that way. Otherwise you need to use the struct keyword everywhere. Check documentation
So you want to say:
typedef struct element {
int i;
element *next;
} element;
when you declare element. Otherwise the compiler doesn't know that element is a structure every time you use it.
h = (element *) malloc(sizeof(element));
h = NULL;
headPointer = (element **) malloc(sizeof(element));
This is your first error. element is a struct tag, not a typedef. (this has been handled by the others.)
in the loop:
headPointer = &h;
Both pointers have been assigned (malloc()d) values. By re-assigning them, you lose the stuff what was previously malloc()d.
The 'headPointer' stuff is a good idea. It is a pointer that can point to other pointers. You can use it to let a called function alter the the value of on of the callers pointers. But your usage is not right. Normally the caller should do:
struct clown *pipo=NULL;
...
my_function( &pipo);
Inside the function, the caller's pointer can than be altered:
void my_function (struct clown **ppp) {
...
*ppp = malloc (sizeof (struct clown));
...
}
After the function returned, the caller can use the pointer, and it will hopefully point at the new clown.
That's all.

Resources