Compiling error for linked list in c - 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.

Related

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

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.

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.

'list' undeclared (first use in this function)

I have below code.
I am getting error as 'list' undeclared (first use in this function).
Please help me
#include <stdio.h>
#include <stdlib.h>
struct list{
int data;
struct list *next;
};
typedef struct list *head;
int main()
{
struct list *start;
int i;
start = (list *) malloc(sizeof(struct list));
printf("\nEnter the data : \n");
scanf("%d", &i);
start->data = i;
start->next = NULL;
while(list->next != NULL)
{
printf("%d ", list->data);
list = list->next;
}
return 0;
}
You're using the type list instead of variable name start. Proper code:
while (start->next != NULL)
{
start = start->next;
// etc.
}
Don't cast the return type of malloc - there's no benefit of it and in this case you did it wrong!
start = (list *) malloc(sizeof(struct list));
should be
start = malloc(sizeof(struct list));
the type list * doesn't exist; you meant struct list *.
You can make it even more safe by writing
start = malloc(sizeof(*start));
this way you automatically malloc enough bytes for the (pointer) type of start, which is useful when you later change the type of start - the malloc call doesn't change a bit.
The
start = (list *) malloc(sizeof(struct list));
includes an unnecessary typecast. Just do
start = malloc(sizeof(struct list));
However, your code has more trouble than this. I can answer your question best by asking a question of my own: in your mind, is list a type or an object?
If you answer this question, one suspects that you can fix your code. Good luck.
#include <stdio.h>
#include <stdlib.h>
typedef struct list{
int data;
struct list *next;
} list;
typedef struct list *head;
int main()
{
struct list *start;
int i;
start = (list *) malloc(sizeof(struct list));
printf("\nEnter the data : \n");
scanf("%d", &i);
start->data = i;
start->next = NULL;
while(start->next != NULL)
{
start = start->next;
}
return 0;
}
you can define the type (list *)
Your variable is named « start » and you called it « list ».
start = (struct list *) malloc ...
You've missed struct in casting.
Which is not neccessary at all as Anthales pointed out.
start = malloc ...
One problem you had is you were re-using struct in declaring your struct pointer after you had created a typedef, struct list *start;. Also the struct and typedef cannot have the same name. You get this:
cc -Wall test.c -o test
test.c: In function ‘main’:
test.c:13: error: ‘list_t’ undeclared (first use in this function)
test.c:13: error: (Each undeclared identifier is reported only once
test.c:13: error: for each function it appears in.)
test.c:13: error: ‘start’ undeclared (first use in this function)
test.c:13: error: ‘cur’ undeclared (first use in this function)
test.c:13: warning: left-hand operand of comma expression has no effect
test.c:16: error: expected expression before ‘)’ token
You can choose to use struct list everywhere and skip making using typedef. Use of typedef simplifies how your code reads as noted here: http://en.wikipedia.org/wiki/Struct_%28C_programming_language%29#typedef
I've rewritten what you have just so I could compile it and understand it a little better, and so I could put some data into one node. I remember the whole struct typedef concept taking a little time to sink in, when I was learning C. So, don't give up.
#include <stdio.h>
#include <stdlib.h>
struct list {
int data;
struct list *next;
};
typedef struct list list_t;
int main()
{
list_t *start, *cur;
int i;
start = (list_t *) malloc(sizeof(list_t));
if (NULL != start)
{
cur = start; /* Preserve list head, and assign to cur for list trarversal. */
printf("\nEnter the data : ");
scanf("%d", &i);
cur->data = i;
cur->next = NULL;
cur = start;
while(cur != NULL)
{
printf("%d ", cur->data);
cur = cur->next;
}
}
else
{
printf("Malloc failed. Program ending.");
}
return 0;
}

Getting "node has no member" error in GCC (c99) for basic trie structure

I'm trying to implement a basic trie structure in plain old C, and I'm getting a "node has no member" error upon compilation.
Here is my structure definition:
typedef struct node {
bool word;
struct node *alpharray[26];
} node;
My attempts to initialize some nodes are as follows:
node *root = malloc(sizeof(node));
node *nptr = malloc(sizeof(node));
nptr = root;
The above code uses "iterator" as the pointer that will cycle through the given trie structure as it's being created. Here's how that works:
while (ch != '\n' && !feof(fp))
{
//get the array index value for the current character (ch)
//getCharNum() returns an int 0-25 corresponding to a slot for a node's alpharray
int char_num = getCharNum(ch);
//if a character has not been put in the given slot yet, make a new node and point
if (nptr->alpharray[char_num] == NULL)
{
node *newnode = malloc(sizeof(node));
nptr->alpharray[char_num] = newnode;
nptr = newnode;
}
//otherwise, move the main pointer to the next node in the chain of nodes
else
{
nptr = nptr->alpharray[char_num];
}
//get the next character
fread(&ch, sizeof(char), 1, fp);
}
The error I get when compiling repeats each time I try to access and/or change any given node attribute. I have also tried the *node.alpharray notation, which as I understand is the equivalent to the above because node will be dereferenced.
I know it's probably something basic I'm overlooking, but I can't seem to find a solution anywhere. Ideas?
Here is the compiler output:
gcc -ggdb -std=c99 -Wall -Werror -c -o dictionary.o dictionary.c
dictionary.c:30:15: error: expected ':', ',', ';', '}' or '__attribute__' before '=' token
dictionary.c: In function 'load':
dictionary.c:74:21: error: 'node' has no member named 'alpharray'
dictionary.c:77:21: error: 'node' has no member named 'alpharray'
dictionary.c:84:28: error: 'node' has no member named 'alpharray'
dictionary.c:71:17: error: variable 'char_num' set but not used [-Werror=unused-but-set-variable]
dictionary.c:93:16: error: 'node' has no member named 'word'
cc1: all warnings being treated as errors
make: *** [dictionary.o] Error 1
You are forgetting to initialise the pointers in the array. Try:
struct node {
bool word;
struct node *alpharray[26];
};
struct node *node_new(void)
{
struct node * ret;
unsigned uu;
ret = malloc (sizeof *ret);
if (!ret) return ret;
ret->word = false;
for (uu = 0; uu < 26 ; uu++) {
ret->alpharray[uu] = NULL;
}
return ret;
}
int main(void)
{
struct node *root , *nptr;
root = node_new();
for (nptr=root; (ch = fgetc( fp)) != EOF; ) {
if (ch == '\n') break;
//get the array index value for the current character (ch)
//getCharNum() returns an int 0-25 corresponding to a slot for a node's alpharray
int char_num = getCharNum(ch);
//if a character has not been put in the given slot yet, make a new node and point
if (nptr->alpharray[char_num] == NULL)
{
nptr->alpharray[char_num] = node_new();
}
nptr = nptr->alpharray[char_num];
}
}
If you initialize your node as :
node *nptr = malloc(sizeof(node));
You create space for the node itself, but not for each of the pointers in
struct node *alpharray[26];
Since alpharray will be NULL you cannot use it to get an element of it directly. You have to malloc for those elements too.
Your 'alpharray' should be declared as:
struct node** alpharray[26];
because in the line:
nptr->alpharray[char_num] = newnode;
you ares assigning pointer to a structure (which is illegal).
Your node declaration should be:
typedef struct node {
bool word;
struct node** alpharray[26];
} node;
When compiler sees your (original) declaration of 'alpharray' it cannot figure out
the size of each element in an array (because the type is not yet fully defined).
That is why it cannot work any other way than with a array of pointers (what you did is an array of 'struct node', not an array of pointers to 'struct node' - what you should do).

incompatible pointer type error C

So I'm trying to implement a cache in C. I have included a very slimmed down version of my code.
I keep getting this error:
prog.c: In function ‘addtolist’:
prog.c:29: warning: assignment from incompatible pointer type
prog.c:40: warning: assignment from incompatible pointer type
prog.c: In function ‘main’:
prog.c:72: warning: assignment from incompatible pointer type
from this code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct node_
{
char * word;
int filenumber;
struct node * next;
};
typedef struct node_ * node;
node createnode()
{
node head;
head = malloc(sizeof(struct node_));
head->word = NULL;
head->next = NULL;
return head;
}
unsigned int addtolist(node head, char * word, unsigned int limit, int fileno)
{
unsigned int templimit = limit;
node temp;
node temphead = head;
while(temphead->next != NULL)
{
temphead = temphead->next;
}
temp = malloc(sizeof(struct node_));
temp->word =(char*) malloc(strlen(word)+ 1);
strcpy(temp->word, word);
temp->next = NULL;
temp->filenumber = fileno;
templimit = templimit - (strlen(word) + 1) - sizeof(struct node_)- sizeof(int);
printf("templimit is size %u\n", templimit);
if (templimit < limit && templimit > 0)
{
temphead->next = temp;
limit = limit - strlen(word) - 1 - sizeof(struct node_)- sizeof(int);
return limit;
}
else
{
free(temp->word);
free(temp);
return 0;
}
}
int main()
{
node newlist = createnode();
int i = 0;
unsigned int limit = 65;
unsigned int temp = limit;
while(temp > 0 && temp <= limit)
{
temp = addtolist(newlist, "Hello", temp, i);
i++;
printf("new limit is - \t%u\nfilenumber is - \t%d\n", temp,i);
}
node ptr = newlist;
while(ptr->next != NULL)
{
printf("node %d contains the word %s\n", ptr->filenumber, ptr->word);
ptr = ptr->next;
}
return 1;
}
I honestly can't figure out what I'm doing wrong... My logic was that, since I was typedef'ing my struct as a pointer, after I created the struct in memory, I would be able to easily step through the ensuing list. Where was the flaw in my logic?
EDIT the initial problem was fixed (I forgot an underscore in my type declaration for struct node_ next;.
Now I'm having another problem: when I try to step through the list at the bottom of my code to print out the words contained in the list, I'm basically not able to step through the list. I keep outputting:
templimit is size 43
new limit is - 43
filenumber is - 1
templimit is size 21
new limit is - 21
filenumber is - 2
templimit is size 4294967295
new limit is - 0
filenumber is - 3
node 0 contains the word (null)
node 0 contains the word Hello
For some reason, it seems that my program isn't storing my changes to my list in memory after the first iteration. Any ideas on what I'm doing wrong?
Once again, any help would be appreciated, and thanks.
Inside your structure definition you have struct node without the underscore.
you'd better have a forward declaration
typedef struct node node;
and then declare your structure
struct node {
...
node *next;
};
no need to have this underscore stuff and hiding the * in a typedef. That only makes you mix things up easily.
String literals "like this" have type const char*, not char*, because they're immutable.
Fix your declarations to have const char* and the warnings will go away.
I think the struct member 'next' has to be declared as a (node_ *) type. As written it is currently (node_ **)

Resources