This is my code to add node at beginning.
void screate(ll *node)
{
ll *newNode=(ll *)malloc(sizeof(ll));
printf("Enter number :\t");
scanf("%d",&newNode->data);
if(newNode->data != NULL)
{
newNode->next=node;
node= newNode;
screate(node);
}
else
{
free(newNode);
newNode=NULL;
}
}
Even i found same code here, I unable to figure out, why I getting wrong output.
This is the current node
56->78->77->NULL
But, when i'm trying to add new node at the beginning, then still I'm getting same output i.e. 56->78->77->NULL. Need Help !!
UPDATE
void show(ll *node){
while(node->next != NULL)
{
printf("%d->",node->data);
node=node->next;
}
printf("NULL");
}
You're assigning to node which is just a parameter to the function. Since it's passed by value, this won't update the version held by the calling function.
You need to pass a pointer to it instead (i.e. ll **node) and change your code to assign to *node, and also changer the caller to add a & before the argument to take its address.
void screate(ll **node)
{
ll *newNode=malloc(sizeof(ll));
printf("Enter number :\t");
scanf("%d",&newNode->data);
if(newNode->data != NULL)
{
newNode->next=*node;
*node= newNode;
screate(node);
}
else
{
free(newNode);
}
}
If you pass a pointer to something to a function, it can change the something but not the pointer itself. The natural conclusion is therefore to make the something itself the pointer - i.e. a pointer to a pointer.
In principle you can take this pointer chaining as deep as you like, but in practice you won't generally need anything more than "pointer to pointer to thing".
Couple of other points. Try to avoid variable names like l and ll as lowercase L's can easily be confused with the digit 1 (and an uppercase I) in many fonts. Also, your use of a recursive call into screate() again would be potentially more efficient as a while loop instead. Some compilers will spot that it's tail-recursive and optimise to a loop anyway, but I never like to rely on that sort of thing when it's just as clear to use a loop in the first place.
newNode->next=node;
node = newNode;
The problem is that node = newNode only changes the local copy of node which means the caller doesn't see the change. For the caller it's as if you never called the function, node still points to wherever it pointed before.
You may want to pass a ll **node and change *node or something else.
You should change the signature with parameter as a pointer to linked list pointer
void screate(ll **node);
And your corresponding pointer changes in your function must be like this
newNode->next=*node;
*node= newNode;
screate(&node);
I would suggest changing your screate function so that it returns a struct ll *. The return value would correspond to your new head node.
if(newNode->data != NULL) is not a sensible way to detect input failures from scanf. In fact, that line of code isn't sensible, period. NULL is identified as a member of the set of null pointers. newNode->data is an int, not a pointer. Comparing it to 0 would make more sense. [Here][1] is a standardised scanf reference. Read it carefully and answer the following questions, and you will know how to distinguish between success and failure of scanf:
int x, y;
int z = scanf("%d%d", &x, &y);
int c = getchar();
If I send "abcd{enter}" through stdin, what will z be?
If I send "abcd{enter}" through stdin, what will c be?
If I send an EOF signal through stdin, what will scanf return?
Which value would z be, if it successfully read and put values into the two variables x and y?
Related
I declared a linked list implemented in C as follows:
struct node_List {
int i;
char * name;
struct node_List* next;
};
typedef struct node_List nodeList;
Then I declared the list head globally as:
nodeList list; // head of the list - does not contain relevant data
Finally, I have a function id(char * s) with a string s as th only argument.
nodeType id(char *s)
{
nodeType *p; // another List type
if ((p = malloc(sizeof(nodeType))) == NULL) {
// error: out of memory;
}
nodeList * node = &list;
// printf(" ");
while (node->next != NULL){
node = node->next;
if (strcmp(node->name, s) == 0){
// printf(" ");
// assign node to an attribute in p
return p;
}
}
// error: not found;
}
The problem is, when i run this program and call foo("somestring") the program executes the error: not found part and aborts execution, despite the string somestring being in the list.
I tried executing the very same program by inserting some printf() for debugging purposes, and it works perfectly, except it prints additional characters along with the output.
This happens each time I add some print lines, e.g. if I uncomment the two printf()s which I wrote in the example above (one of them or both, i get the same successful result). It doesn't work though if the printf is called with no arguments or with an empty string "".
I can't figure out what's happening, I double-checked the list creation and population functions and I am totally sure they work correctly. I tried changing the while break condition, but that didn't work, too. I have observed a similar behaviour on both Linux (with gcc) and Windows (using CodeBlocks editor's integrated compiler)
How could a printf directive affect a program so much?
EDIT: This code is part of a syntax analyzer written in Yacc. The whole code can be found below. It's a long read, and it is not completed, but the code above was tested and used to work as explained.
lexer: http://pastebin.com/1TEzzHie
parser: http://pastebin.com/vwCtMhX4
When looking in the provided source code, the algorithm to explore the linked list has two ways to miss node in the while-loop comparison.
Way 1 - starting only from the second node of the list.
Placing node = node->next; before the comparison will force the first comparison to be &(list)->next instead of &(list).
To start from the first node, simply place node = node->next; after
the comparison.
Way 2 - never ending to the last node of the list.
Using (node->next != NULL) in the while condition will force to exit from the loop before comparing the last node => node->next = NULL;.
To end by the last node, simply change the while condition to (node != NULL).
Solution:
while (node != NULL){ // end from the last node
if (strcmp(node->name, s) == 0){
// printf(" ");
// assign node to an attribute in p
return p;
}
node = node->next; // explore link after comparison
}
The actual error is a wrong type declaration of a variable returned by the function:
nodeType* createPoint(char* l){
nodeList* p;
if((p=malloc(sizeof(nodeList))) == NULL){
yyerror("out of memory");
} else {
// do stuff with p
}
return p;
}
The function return value was a nodeType* and p was instantiated as nodeList*.
The declaration of those two types was pretty simple, that's why the program could work.
the working code can be found here.
The strange behaviour with printf() was probably caused by the heap space needed for printf's arguments: since this function accepts an arbitrary number of parameters, it saves them in a list. This list is instantiated in the heap, there overwriting the old data left there from the wrong implementation of createPoint.
I'm just learning C, and I have a question about pointer parameters. My code is the following:
int Length(node *head)
{
int length = 0;
while (head) {
length++;
head = head->next;
}
return length;
}
The code in the book I'm reading says to do this though:
int Length(struct node* head)
{
struct node* current = head;
int count = 0;
while (current != NULL) {
count++;
current = current->next;
}
return count;
}
Is there really a difference? The way I'm reading my code is that I get a pointer to a node struct as a parameter. The pointer itself however, is a local variable that I am free to mutate as long as I don't dereference it first. Therefore, I can change the value of the pointer to point to a different node (the next node as it may be).
Will this cause a memory leak or is there some other difference I'm not seeing?
This code is for a linked list implementation. The node struct is defined as:
// Define our linked list node type
typedef struct node {
int data;
struct node *next;
} node;
Yes, they are both doing the same. But in the second example, it is more clear what the author is trying to do because of the code. In your first example, you're using the pointer head to reference nodes other than the head. That can be confusing.
You could write your function like this and your intend would be clear:
int GetLength(node* current)
{
int length = 0;
while (current != NULL)
{
length += 1;
current = current->next;
}
return length;
}
Your solution and reasoning is correct. The node argument is a local variable: a copy of the pointer passed to your function, allocated on the stack. That's why you can modify it from within the function.
There is no difference between the two solutions, at least not in functionality, modern compilers are most likely to optimize away the extra variable in the book's solution. The only slight difference is in style, many tend to take arguments as unmodifiable values just in case to avoid mistakes.
Your understanding of the argument-passing mechanics is correct. Some people simply prefer not to modify argument values, the reasoning being that modifying an argument tends to be bug-prone. There's a strong expectation that at any point in the function, if you want to get the value the caller passed as head, you can just write head. If you modify the argument and then don't pay attention, or if you're maintaining the code 6 months later, you might write head expecting the original value and get some other thing. This is true regardless of the type of the argument.
so i wrote a program to read words from a file and insert, remove or search them in a binary search tree. It seemed like everything was working fine but somehow when inserting a word in a binary search tree, from the second word onwards the root pointer I pass as the parameter of the insert function is shifted to point at the word being inserted. So instead of inserting the word the function only increases the occurence of the first word. I sincerely don't know how this is happening. Does anyone know what could be the problem?
my structs:
typedef char * TypeKey;
typedef struct TypeItem {
TypeKey Key; //[MAXTAM];
int counting;
} TypeItem;
typedef struct Node * Pointer
typedef struct Node {
TypeItem Reg;
Pointer Left, Right;
} node;
typedef Pointer TypeTree;
The insert function:
void Insert (TypeItem * x, Pointer * p){
if (*p == NULL){
*p= (Pointer)malloc(sizeof(Node));
(*p)->Reg = *x;
(*p)->Left = NULL;
(*p)->Right = NULL;
printf("insert %s\n",x->Key);
return;
}
if (strcmp(x->Key,(*p)->Reg.Key)< 0){
Insert(x, &(*p)->Left);
}
if (strcmp(x->Key,(*p)->Reg.Key) > 0)
Insert(x, &(*p)->Right);
else {
(*p)->Reg.counting ++;
printf("increases %s\n",x->Key);
return;
}
}
And i just declare the root pointer "arvore" on main like this:
Pointer arvore = NULL;
TypeItem item;
item.Key = Palavra;
item.counting = 1;
Insert(&item, arvore);
If anyone could help me understand what is the wrong it would be really nice.
You have undefined behavior in your code
First you declare arvore of type Apontador, and then assign NULL to that pointer. Then you call Insere with arvore as argument, but Insere want a pointer to an Apontador, meaning you have one level of indirection to little in the call. This shouldn't even compile, or at least give a warning (warnings are a very good sign that you're doing something you shouldn't be doing).
And when inside the Insere function, you dereference the pointer p (which is arvore in the call) which is NULL, leading to undefined behavior.
You should call the function using the address-of operator & for the second argument as well:
Insere(&item, &arvore);
Also, if Palavra is a pointer to e.g. an array defined locally in a function, that pointer will no longer be valid once that function returns. If it's so then you have another case of undefined behavior.
[Too long for a comment]
I did not dive to the ground but this line
(*p)->Reg = *x;
copies a TypeItem and with it copies one of its members, namely TypeKey Key with Key being a pointer char *. I strongly assume here a deep copy is needed, you need to duplicate what the pointer Key points to.
It is not fully clear as we do not see who you fully initialies your node.
So here's my code for destroying a linked list.
void destroy(node *h){
if (h->next!=NULL){
destroy(h->next);
}
free(h);
h=NULL;
}
The problem is that printing still outputs a bunch of numbers:
11, 2, 15, 3, 9, //Before Destroy
28495936, 28495968, 28496064, 28496096, 0, //After Destroy
Unfortunately I cannot alter the void destroy(node *h) parameters due to assignment reasons.
I've tried using a while loop method but I still get the same result. I've also tried shifting to the left and deleting from the end but then I wouldn't be able to delete the last node.
thanks in advance.
--edit---
as requested, here is the print function
void print(node* N){
printf("%d, ", N->value);
if (N->next)
print_set(N->next);
if (N == NULL)
printf("Empty Set");
}
You must set h->next = NULL. Also, after the call to destroy, make sure you don't use the pointer anymore because it is freed. So, always after destroy(n), make sure that you have n = NULL.
A better way is probably to change the signature to void destroy(node **h), so the code becomes:
void destroy(node **h){
if ((*h)->next!=NULL){
destroy(&h->next);
}
free(*h);
*h=NULL;
}
Then you ensures that you are not using the pointer afterwards.
In your print function, you must add this check at the beginning:
if(N == NULL) return;
If the solution provided by Albert is not possible due to some rules, the only possibility you as the author of the source in question have is to remember the list's nodes had been deallocated and therefore contain invalid references to memory and that the code you write because of the latter may not dereference such pointers, that is they may not be passed to the printing functions as this would provoke undefined behaviour by accessing un/deallocated memory.
If writing such potential insecure code, it is in your responsibilty as the author to use it carefully and document it very well for your fellow programmers maintaining the code after you left the project.
The problem here is that h=null in your function does not do anything. You're modifying a local parameter so it won't have any effect outside the function.
Thus, the only thing you do is freeing the memory, but you keep the address the same. Your list still exists, pointing to random memory location (well not random : the same as before, but the values at this memory locations are random)
When you print your list after that (which is strange because you're supposed to have destroyed it... Why would you want to print it again ?), you print random values in memory.
This is a problem because your program could also crash (you're accessing memory which is not allocated).
The solution, unfortunately, requires to change the signature of your function :
void destroy(node **h){
if ((*h)->next!=NULL){
destroy((*h)->next);
}
free(*h);
*h=NULL;
}
If you can't, you have to set the pointer to NULL after destroying it, like this:
void destroy(node *h){
if (h->next!=NULL){
destroy(h->next);
h->next=NULL;
}
free(h);
}
and in the calling function:
destroy(myList);
myList=NULL;
The problem is probably in code you haven't posted!
I assume you keep a 'head' pointer to your list, and your code looks like this.
Node * myList;
.. do stuff..
destroy(myList);
print(myList);
The problem is that you don't set myList = NULL following the destroy.
destroy(myList);
myList = NULL;
print(myList);
Your h=NULL in destroy() doesn't do anything because it's modifying a local parameter.
I don't know what your structure looks like, but I'm guessing something like this:
struct {
int something;
int* value;
list* next;
}
The problem is that even though h is the NULL pointer, h->value and h->next are not. They are pointers in NULL+1 and NULL+2, which may point to random places in memory.
Try this code if u are working on singly linked list
void destroy(node *h){
node *n;
node *p; \\ variable to store previous term
n=h;
while(n->next!=NULL){
p = n;
}
p->next=NULL;
free(n);
}
Is there any difference between these two functions? I mean in-terms of the result returned?
int Length(struct node* head) {
struct node* current = head;
int count = 0;
while (current != NULL) {
count++;
current = current->next;
}
return count;
}
and this function
int Length(struct node* head) {
int count = 0;
while (head != NULL) {
count++;
head = head->next;
}
return count;
}
They are the same. One uses a local 'current' variable to iterate over the list, while the other one uses the same variable that was received through the function arguments.
The returned value will be the same.
The former is the kind of code that would be written by a programmer subscribing to the style rule that says "it is bad practice to modify parameters because they are passed by value and would give the reader a false sense that the function would modify the corresponding argument."
Not necessarily bad advice. It makes the code a little longer, though, but it reads better. Many readers look at the second and have an initial reaction of "wait, what? changing the head? Oh... okay, no it's safe...."
No difference. The second version simply uses the function argument itself as a variable to work with in the body, and that's perfectly legitimate. In fact, it's even slightly more efficient than the first version which make a gratuitous copy.
You couldn't use the second version if the argument were declared const, i.e. int Length(struct node* const head) -- but since it isn't, you're free to use the argument variable for your own purposes.