cc compiler issue in C - c

I am trying to write a simple code to construct a tree in C language. Below is my code snippet.
#include<stdio.h>
struct node
{
int data;
struct node *left;
struct node *right;
};
int main()
{
struct node *root = newNode(5);
//struct node *root = NULL; working piece
//newNode(&root,5); working piece
if(root == NULL)
{
printf("No root\n");
return 0;
}
//root->left = newNode(4);
//root->right = newNode(3);
//root->left->left = newNode(2);
//root->right->right = newNode(1);
return 0;
}
struct node* newNode(int data)
{
struct node *temp;
temp = (struct node*) malloc(sizeof(struct node));
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return(temp);
}
When I try to return the structure node address, the compiler gives me the error
"rightNode.c", line 29: identifier redeclared: newNode
current : function(int) returning pointer to struct node {int data, pointer to struct node {..} left, pointer to struct node {..} right}
previous: function() returning int : "rightNode.c", line 12
But when I comment this struct node* newNode(int data) and try to define a function that returns int by passing the address of the structure to the function like below, it does not shows me any error.
int newNode(struct node **root,int data)
{
printf("Inside New Node\n");
return 0;
}
As far I know, it is legal in C to return the address of the structure to the calling function.
It is something to do with the compiler.
I am using cc compiler in unix environment
type cc
cc is a tracked alias for /apps/pcfn/pkgs/studio10/SUNWspro/bin/cc
Below is the command I used to compile cc rightNode.c
Any help would be appreciated...

You need to declare a newNode prototype before you use it.
// somewhere after struct node definition and before first use
struct node* newNode(int);
You also need to include stdlib.h to get malloc.

Put this struct node* newNode(int data) above the code and include stdlib.h.
You need a function prototype if you are going to use a function before you declare it. Also malloc is defined in stdlib.h.

There is no function prototype visible when you call struct node *root = newNode(5); so the compiler gets confused.

When the compiler cannot find a function declaration, it assumes that such function exists, but returning int. Declare struct node* newNode(int data); before you call newNode(...) in main.

In older versions of C, you did not need to declare a function before using it. In older C, functions that are not declared are assumed to return int and accept an unspecified number of arguments. This is the reason you are getting the error, because the compiler assumes the newNode function returns int, rather than struct node *.
In modern C (C99 and newer), you can no longer do this. You must declare functions before they are used. Some compilers still allow the old behaviour and warn against it, but a strictly conforming C99 program cannot use a function without declaring it first.
In your case, you should put the following line of code before your main function. This tells the compiler about the newNode function and how it should be called:
struct node *newNode(int);

Related

init() function call in C

I am following an online tutorial which presents me with the following (simplified) code:
typedef struct {
int data;
Node* next;
} Node;
int main(){
Node *head;
init(&head);
return 0;
}
What is the purpose & functionality of the init function? I did not define it myself, however am struggling to find documentation online as well.
For starters this declaration
typedef struct {
int data;
Node* next;
} Node;
is incorrect. The name Node used in this data member declaration
Node* next;
is undefined.
You need to write
typedef struct Node {
int data;
struct Node* next;
} Node;
As for your question then in this declaration
Node *head;
the pointer head has an indeterminate value because it is not initialized.
So it seems the function init just initializes the pointer. You need to pass the pointer by reference through a pointer to it. Otherwise the function will deal with a copy of the pointer head. Dereferencing the pointer to pointer you will get a direct access to the original pointer head that can be changed within the function. That is the function can look the following way
void init( Node **head )
{
*head = NULL;
}
Pay attention to that you could just write in main
Node *head = NULL;
without a need to call the function init.
I think that the init function is gonna be implemented in the next videos. I suppose that your teacher wants to use an init function to set some values if you create a new Node (or a struct in this case) to prevent some easter eggs undefined behaviour.

Simple C code illustrated in class doesn't work (typedef related)

The following piece of code does not compile in Eclipse:
typedef int Data;
typedef struct node* Node;
typedef struct node {
Data data;
Node next;
};
int main() {
Node n = newNode();
return 0;
}
Node newNode() {
Node newNod;
newNod = malloc(sizeof(struct node));
if(!newNod){
return NULL;
printf("\naa");
}
newNod->data = 3;
return newNod;
}
The one error displayed on compile time is
error: conflicting types for 'newNode'* (line with newNode() method declaration "Node newNode() {").
I'm clueless. What's wrong?
Move the definition of newNode above main [or add a forward declaration of newNode above main].
In your code, when the compiler sees the call to newNode in main, it is using an implicit declaration. When the actual definition is encountered, it doesn't match that
The statement
typedef struct node {
Data data;
Node next;
};
is not correct. The typedef requires a name for the type like you did in typedef struct node* Node;.
Since you only want to define struct node without a typedef, you should remove the word typedef in this statement:
struct node {
Data data;
Node next;
};
There is an ancient idea, prior to the c language being standardized where a function that has been called but not yet declared, is implicitly declared. In such declaration the return value would be int by default.
After the implicit declaration, comes the definition so the compiler is confused.
There are 2 solutions to this,
Delcare the function before main(), i.e. add
Node newNode();
before main().
Move the entire newNode() definition before main().
Now that we've addressed the problem, please note that typedefing a pointer is a bad idea. It's not immediately clear from the code that variables of such type are really pointers. And since there's a very important difference whether they are pointers or not, you should make it as clear as possible.

Pointer to declared but uninitialized variable in C

I've been reviewing the basics of singly linked list In C with materials from Stanford CS Library, where I came cross the following code:
struct node{
int data;
struct node* next;
};
struct node* BuildWithDummyNode(){
struct node dummy;
struct node* tail = & dummy; // this line got me confused
int i;
dummy.next = NULL;
for (i=1;i<6;i++){
Push(&(tail->next), i);
tail = tail->next;
}
return dummy.next;
}
Probably not revenant, but the code for Push() is:
void Push(struct node** headRef, int data){
struct node* NewNode = malloc(sizeof(struct node));
newNode->data = data;
newNode->next = *headRef;
*headRef = newNode;
}
Everything runs smoothly, but I've always been under the impression that whenever you define a pointer, it must point to an already defined variable. But here the variable "dummy" is only declared and not initialized. Shouldn't that generate some kind of warning at least?
I know some variables are initialized to 0 by default, and after printing dummy.data it indeed prints 0. So is this an instance of "doable but bad practice", or am I missing something entirely?
Thank you very much!
Variable dummy has already been declared in the following statement:
struct node dummy;
which means that memory has been allocated to it. In other words, this means that it now has an address associated with it. Hence the pointer tail declared in following line:
struct node* tail = & dummy;
to store its address makes perfect sense.
"But here the variable "dummy" is only declared and not initialized."
The variable declaration introduces it into the scope. You are correct in deducing it's value is unspecified, but to take and use its address is well defined from the moment it comes into scope, right up until it goes out of scope.
To put more simply: your program is correct because you don't depend on the variables uninitialized value, but rather on its well defined address.

assignment from incompatible pointer type in linked list?

I am new bee to C. I am currently writing linked list in C. When compiling, it keeps complaining about "assignment from incompatible pointer type". My code is like this:
# include <stdio.h>
#include <stdlib.h>
struct snode{
struct snode *next;
int val;
};
struct slist{
struct snode *head;
struct snode *tail;
int len;
};
struct slist *mylist;
void slist_insert(int v){
struct snode *newnode;
newnode = (struct snode*)malloc(sizeof(struct snode));
newnode -> val = v;
newnode -> next = NULL;
if(mylist->head = NULL){
mylist->head = malloc (sizeof(struct snode));
mylist->tail = (struct snode*)malloc (sizeof(struct snode));
mylist->head = newnode;
mylist->tail = newnode;
};
else{
mylist -> tail -> next = (struct snode*)malloc (sizeof(struct snode));
mylist -> tail -> next = newnode;
};
mylist -> len +=1;
};
main(){
slist_insert(1);
slist_insert(2);
slist_insert(3);
slist_insert(4);
slist_insert(5);
struct snode *temp;
temp = (struct snode*)malloc(sizeof(struct snode));
temp = mylist-> head;
while(temp -> next != NULL){
printf("%d\n", temp -> val);
temp = temp -> next;
};
};
Here is the modified one. I am using linux terminal to run this program. The compiler I am using is gcc -std=gnu99
UPDATE
slist.c: In function â:
slist.c:32: error: â without a previous â
slist.c: At top level:
slist.c:40: warning: return type defaults to â
There are many problems with this code. I am ONLY listing the problems that cause the "assignment from incompatible pointer" warnings. Compile with gcc -W -Wall and fix all the warnings. And after you've done that there will still be bugs.
You need #include <stdlib.h>, right after the existing #include <stdio.h>, to make the declaration of malloc visible. (If you don't do this, the compiler is obliged to assume that malloc returns int, even though it knows perfectly well that that's wrong. This is what the "incompatible implicit declaration of built-in function ‘malloc’" warning is trying to tell you.)
You are incorrectly casting struct snode allocations to struct slist * and then assigning them to struct snode * fields, in several places. Do not cast the return value of malloc to anything; just assign it. (Note that you may see people deliberately casting the return value of malloc in code that needs to be compilable as C++ as well as C. Do not do this until you are experienced enough to understand when it is necessary. If your compiler insists on treating everything as C++ even when it's meant to be C, get a better compiler.)
struct snode's next field should be declared as struct snode *, not int *.
Your nextis a pointer to int, while you want it to be a pointer to struct snode, I assume.
Moreover, I assume that your mylist is supposet to be an slist instead of a pointer to an slist. And as has been pointed out in the comments, that membres of that mylist are not necessarily initialized (implementaiton dependent. With your mode of using a pointer for mylist, you need to malloc (and init) that guy first ...

How to declare a linked list in c

struct node {
int data;
struct node *next,*prev;
};
void insert(struct node *head,int data){
if(head == NULL){
head = (node *)malloc(sizeof(node));
--- code continues-----
I just want to know the difference between
head = (node *)malloc(sizeof(node)); and struct node *head = malloc(sizeof(struct node));
And if I pass **head as a parameter of the insert function what does it do ?
The difference between:
head = (node *)malloc(sizeof(node));
struct node *head = malloc(sizeof(struct node));
is that a C compiler will reject the first and allow the second, but a C++ compiler will accept the first and reject the second.
In C, the code shown does not create a type name node when you define or declare struct node. You would need to add typedef struct node node; in the C source. C++ automatically creates the type name node from the definition of struct node. (A C++ compiler rejects the second because of the implicit cast from void * to struct node *; C++ does not allow that, and would require struct node *head = (struct node *)malloc(sizeof(struct node));)
And if I pass **head as a parameter of the insert function, what does it do?
You'd have to adjust the body of the function, but it would allow you to change the location of the head of the list in the calling function.
The answer for your first question is:
head=(node *)malloc(sizeof(node));
malloc() returns a pointer of type void so here you are explicitly converting it to a pointer of type node .But remember, in C a pointer of type void() converts implicitly into the type of pointer that it is assign to. So if you write like:
head=malloc(sizeof(node));
It will stil work correctly. But with the C++ compiler it is not the case, In C++ pointer of type void is not implicitly cast to the type of pointer that it it assign to.
Also to answer your question,
void insert(struct node *head,int data)
If you pass **head as parameter it will show an error declaring that the type of operator is not matched. This is because you had declared it as struct node *head not as struct node **head.
If you type in
typedef struct node{
int data;
struct node *next, *prev;
} node;
the compiler will accept your head = (node *)malloc(sizeof(node)); code. Remember that typedef allows you to use the struct the same way it's used in C++.
Technically there isn't a difference between sizeof(node) and sizeof(struct node) (at least in C++), since both will return the size of the struct.
In C however it's mandatory to write struct node, just like it's mandatory to write struct node when declaring a variable of that type, simply because there is no type node.
C only understands primitives (int, char, long) and custom types declared with struct. Every C compiler is very strict with this keyword struct and assumes you're talking about a variable if you forget it.
Regarding your second question: You can't. You can't pass a pointer to a pointer to a function, which only accepts a regular pointer, unless you cast it. In that case however, it will point to a completely arbitrary position on the stack (where your pointer is located) and probably make your program crash.
create (struct node **p)
{
struct node *temp,*q;
int n;
printf("enter the length of link list");
scanf("%d".&n);
while(n>0)
{
if(*p == NULL)
{
*p=(struct node*)malloc(sizeof(struct node*));
printf("enter the element");
scanf("%d".&((*p)->data));
(*p)->next=NULL;
}
else
q=*p;
while(q->next=NULL)
q=q->next;

Resources