I have a small piece of code, compiled well. But it appears segmentation fault at runtime.
#include <stdlib.h>
#include <string.h>
typedef struct ListElmt_ // Define a structure for linked list elements.
{
void *data;
struct ListElmt_ *next;
} ListElmt;
typedef struct List_ //define a structure for linked lists.
{
int size; // the size of the linked list
ListElmt *head; // the head element
ListElmt *tail; // the tail elemtent
} List;
void list_init(List *l)
{
l->size = 0;
l->head = NULL;
l->tail = NULL;
}
int main()
{
List *ls = NULL;
list_init(ls);
return 0;
}
I have tried but could not find out what's wrong. Please help? I am a newbie, could anyone suggest me tools to find this kind of error?
Your failing line is:
l->size = 0;
Since you initialized ls to NULL the above line is doing NULL->size, i.e. an illegal dereference. You need to allocate memory for ls first.
However, there is no reason for a dynamic allocated List. Simply do:
int main()
{
List ls; // Don't make list a pointer - just an ordinary var
list_init(&ls); // Pass the address of ls (i.e. &ls) as the function
// expects a pointer.
return 0;
}
To find the kind of problem, you had with the pointer version, you could use a debugger and use single-step, i.e. execute the code line-by-line until you hit the failing point. Another way is to insert a number of printf statements so that you can see what the code did just before crashing.
The variable ls should be provided memory location before any access.
Use: ls = malloc(sizeof(List)); before use of ls.
A segmentation fault usually appears when trying to access a memory location which does not exist yet.
Related
Hi guys I'm learning C programming. I wanted to write some codes for learning linked list topic but there is a problem. This code about creating linked list with 5 nodes, writing something into 3rd node, printing them to console.
Here is all of my codes:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
struct node{
char *data;
struct node *next;
};
typedef struct node node;
node *root;
void nodeAdd(node *n, int x)
{
node *iter;
iter=root;
for(int i=0;i<x;i++)
{
iter->next = (node*)malloc(sizeof(node));
iter->next->data="0";
iter->next->next=NULL;
iter=iter->next;
printf("Node created.\n");
}
}
void nodeWrite(node *n,char *string,int x)
{
node *temp;
temp=root;
for(int k=0;k<x;k++)
{
temp=temp->next;
}
strcpy(temp->data,string); //HERE IS ERROR
printf("\n");
printf("%s \n",temp->data);
printf("Node writed.");
}
void nodePrint(node *n)
{
while(root->next!=NULL)
printf("%s\n",root->data);
root=root->next;
}
int main(int argc, const char * argv[])
{
root = (node*)malloc(sizeof(node));
nodeAdd(root,5);
nodeWrite(root,"WTF", 3);
nodePrint(root);
return 0;
}
data is an unintialized pointer variable. Initialize with the address of a valid memory that you allocate. That will solve the problem. Now you have udnefined behavior.
What you can possibly do is
Use char array instead of using pointer.
Allocate dynamically the memory.
In case of 1.
struct node{
char data[MAXSTRINGLEN];
struct node *next;
};
In case of 2:
Initially make the pointers point to NULL. So now you can allocate to it like this
temp->data = malloc(sizeof *temp->data*MAXSTRINGLEN);
if( temp->data == NULL)
{
fprintf(stderr,"Error in malloc");
exit(1);
}
Just one point, free the allocated memory when you are done working with it.
Use of the global variable here is not really required here. You can always pass return pointers from memory and assign it to the struct node*. Or yes you can use double pointers. Use of global variable is not needed here.
Clean up code, that are redundant and not required. That makes things readable and less confusing.
The program initially is designed incorrectly and has undefined behavior..
For example the data member data of the node root was not initialized. So its output in the function nodePrint results in undefined behavior. Moreover the function itself is incorrect.
Neither function uses its parameter node *n.
In this statement
strcpy(temp->data,string);
there is an attempt to change the string literal pointed to by the data member temp->data provided that the data member was initialized (as it was pointed above the data member is not initialized for the node root). You may not change a string literal. Any attempt to modify a string literal leads to undefined behavior.
There is no need to declare the node root as a global variable.
Parameters of the function main are not used in the program. So the function should be declared like
int main( void )
I am pretty new to C and I was wondering if the order of elements in a struct matter.
I have the following struct:
struct list
{
struct list_el *head;
int size;
}
I use this to make a linked list. The head points to the first element and the size shows the amount of elements in the list.
I have also have the following function to initialize the list.
typedef struct list list;
list* list_init()
{
list *list = malloc(sizeof(list));
if(list)
{
list->head = NULL;
list->size = 0;
return list;
}
return NULL;
}
The program compiles fine, without any errors, warnings or notes, but when I run the program using valgrind it says I have an invalid write of size 4 on the line in the list_init() function where I assign 0 to list->size. I have the same invalid read/write every time I access the size variable. I have no idea why. Also when I switch the two struct elements around (declare size first and then head) I get the invalid write on the line where I assign NULL to head and then the size variable is used just fine. Can anybody explain me why this happens and how I can fix it?
Last note: the struct as it is shown here is defined in an header file while the function is in the C file. Not sure if this is important.
You named the variable with the same name as the type, so sizeof(list) is implemented as the size of the variable (pointer), not the size of the struct. The struct has a pointer and a integer, so the size will be larger than a pointer, so access to not allocated place occurred.
Rename the variable.
example:
list *list_init(void)
{
list *list_data = malloc(sizeof(list));
if (list_data)
{
list_data->head = NULL;
list_data->size = 0;
return list_data;
}
return NULL;
}
So I'm doing some linked list revison and Im trying to just load a list with some numbers and then print it out. Below is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct stack {
int data;
struct stack *next;
}*stack;
stack create_s(void){
stack s = (void*)malloc(sizeof(stack));
s->next = NULL;
return s;
}
void push_s(stack s, int data) {
while (s->next != NULL) {
s = s->next;
}
s->next = (void*)malloc(sizeof(stack));
s=s->next;
s->data = data;
s->next = NULL;
}
void print_s(stack s) {
if (s==NULL) {
return;
}
else {
while (s->next != NULL) {
printf("%d\n",s->data);
s=s->next;
}
}
}
int main (void) {
stack s = create_s();
push_s(s,2);
push_s(s,4);
push_s(s,6);
push_s(s,8);
print_s(s);
return 0;
}
My output is however:
-1853045587
2
4
6
when it should be
2
4
6
8
Is it printing the address of my struct at the beginning? Also, why is it not printing my last element?
Thanks
The code contains several errors, but the first thing that catches the eye is that your memory allocation is already obviously broken
stack s = (void*)malloc(sizeof(stack));
You defined stack as a pointer type. This means that sizeof(stack) evaluates to pointer size and the above malloc allocates enough space to store a single pointer, not enough for the entire struct stack object. The same memory allocation error is present in push_s as well.
Here's some advice
Don't hide pointer types behind typedef names. Define your stack as
typedef struct stack{
int data;
struct stack *next;
} stack;
and use stack * wherever you need a pointer. I.e. make that * visible instead of hiding it "inside" a typedef name. This will make your code easier to read.
Don't cast the result of malloc. Anyway, what is the point of casting it to void * when it is void * already???
Don't use sizeof with types unless you really really have to. Prefer to use sizeof with expressions. Learn to use the following malloc idiom
T *p = malloc(sizeof *p);
or, in your case
struct stack *s = malloc(sizeof *s);
This will allocate a memory block of appropriate size.
Also, as #WhozCraig noted in the comments, the very first node in your list is apparently supposed to serve as a "sentinel" head node (with undefined data value). In your code you never initialize the data value in that head node. Yet in your print_s function you attempt to print data value from the head node. No wonder you get garbage (-1853045587) as the first line in your output. Don't print the very first node. Skip it, if it really is supposed to serve as a sentinel.
Also, the cycle termination condition in print_s looks strange
while (s->next != NULL)
Why are you checking s->next for NULL instead of checking s itself? This condition will terminate the cycle prematurely, without attempting to print the very last node in the list. This is the reason why you don't see the last element (8) in your output.
The actual cause of the given output can be fixed by changing:
s=s->next;
s->data = data;
to
s->data = data;
s=s->next;
I am trying to create a doubly linked list in C but it doesn't work and I don't know why. It prints only the last element that I introduce. I do not see any problem at the part of code that creates the list. Maybe you can see it?
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
struct node *prev;
}NodeT;
struct d_linked_list
{
NodeT *first;
NodeT *last;
};
int main()
{
int d;
struct d_linked_list *l;
NodeT *p,*q;
p=(NodeT*)malloc(sizeof(NodeT));
q=(NodeT*)malloc(sizeof(NodeT));
l->first=NULL;
l->last=NULL;
while (fscanf(stdin,"%d",&d)!=EOF)
{
p->data=d;
if (l->first==NULL)
{
l->first=p;
l->last=p;
p->next=NULL;
p->prev=NULL;
}
else
{
l->last->next=p;
p->prev=l->last;
l->last=p;
}
}
l->last->next=NULL;
for (q=l->first;q!=NULL;q=q->next)
printf("%d ",q->data);
return 0;
}
As so often, there are a number of problems, some of them already identified in other answers or in comments and some (I think) not identified before:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
struct node *prev;
}NodeT;
struct d_linked_list
{
NodeT *first;
NodeT *last;
};
So far, so good.
int main()
{
int d;
struct d_linked_list *l;
You don't allocate space for l. It would probably be simpler (maybe better, therefore) to use:
struct d_linked_list head; // Or maybe list instead of head
and then refer to head in your code instead of l; you could also use l = &head; without further changes.
NodeT *p,*q;
p=(NodeT*)malloc(sizeof(NodeT));
q=(NodeT*)malloc(sizeof(NodeT));
You never use the space allocated for q and you eventually overwrite it, thus leaking. You should check that malloc() worked, doing something appropriate (stop with an error message?) if it has failed.
l->first=NULL;
l->last=NULL;
while (fscanf(stdin,"%d",&d)!=EOF)
You should check that you got one integer with while (fscanf(stdin, "%d", &d) == 1); the loop breaks on EOF or on a conversion failure.
{
p->data=d;
You allocated p before the loop, but each subsequent entry is overwriting the same space. You need to allocate a new node for each value you read. (This was not previously identified as an issue — though I see Filipe Gonçalves added it to his answer while I was typing mine.)
if (l->first==NULL)
{
l->first=p;
l->last=p;
p->next=NULL;
p->prev=NULL;
}
else
{
l->last->next=p;
p->prev=l->last;
l->last=p;
}
}
Superficially, the code above looks OK; I've not run it, so there could be issues I've not spotted.
I noted 'not thoroughly checked' and indeed there are problems, as Filipe pointed out. The if clause is OK, I think, but the else clause needs to set p->next = NULL;. In general, it is a good idea to create the node completely: p->data = d; p->next = NULL; p->prev = NULL: and then hook the node into the list.
l->last->next=NULL;
This line should be unnecessary. At the end of each cycle of the loop, the list should be correctly formed. One way to test this is to print out the contents of the list (using a function) on each cycle. You'd also use that function in place of the loop that follows. An interface design that I often use is:
void dump_list(FILE *fp, char const *tag, struct d_linked_list const *list)
which prints the identifying tag and the contents of the list on the given file stream. I keep such functions around for every significant data structure so that debugging is easier later.
for (q=l->first;q!=NULL;q=q->next)
This loop loses track of the space allocated to q.
printf("%d ",q->data);
You should output a newline at some point.
You should also go through the motions of releasing all the space allocated, simply to make sure you know how you could do that. When you're about to exit a program, it isn't crucial, but if you were using the list in a long-running program that needs a list once a minute, then goes off and does unrelated operations, then you'd be leaking all that memory and your long-running program would stop running after a while because it lacked the necessary memory (because it had leaked — wasted — the memory in the lists).
return 0;
}
Try moving p=(NodeT*)malloc(sizeof(NodeT)); into the top of the loop. Also, you don't need to malloc the value in q.
You never allocate space for l. Therefore, these lines are dereferencing an invalid pointer:
l->first=NULL;
l->last=NULL;
You must allocate space for l before using it:
l = malloc(sizeof(*l));
l->first=NULL;
l->last=NULL;
Also, you need to allocate a new element for each new value that you read. Thus, I would move the allocation for p into the loop:
q=(NodeT*)malloc(sizeof(NodeT));
l->first=NULL;
l->last=NULL;
while (fscanf(stdin,"%d",&d)!=EOF)
{
p=(NodeT*)malloc(sizeof(NodeT));
/* ... */
}
And you don't need to allocate space for q (you use it only for traversing the list). Finally, as pointed out in a comment, you should check if fscanf() returned 1, because only in that case you can be sure that d contains a valid value.
Putting this all together:
int main()
{
int d;
struct d_linked_list *l;
NodeT *p,*q;
if ((l = malloc(sizeof(*l))) == NULL) {
/* Handle malloc error */
}
l->first=NULL;
l->last=NULL;
while (fscanf(stdin,"%d",&d) == 1)
{
if ((p = malloc(sizeof(*p))) == NULL) {
/* Handle malloc error... */
}
p->data=d;
p->next = p->prev = NULL;
if (l->first==NULL)
{
l->first=p;
l->last=p;
}
else
{
l->last->next=p;
p->prev=l->last;
l->last=p;
}
}
for (q=l->first;q!=NULL;q=q->next)
printf("%d ",q->data);
return 0;
}
UPDATE: I changed the code to check for malloc()'s return value, and took that l->last->next = NULL; away - p->next and p->prev are now initialized to NULL inside the loop, there is no need to do it after the loop.
I am attempting to create a Linked List using C (NOT C++). The Linked List is initialized through the function llinit() which should return a list struct. However, when I compile the code I get an error stating "error: invalid initializer" in the lltester.c file. Why is this?
This is the function used to initialize the linked list in my llist.c file:
list llinit()
{
list* ll = malloc(sizeof(list));
ll->head = NULL;
ll->tail = NULL;
return *ll;
}
This is the list struct in my llist.h file:
typedef struct {
node *head;
node *tail;
} list;
This is my main function in my lltester.c file where I attempt to initialize the list:
int main()
{
list myList= llinit(); //This is the line where the error occurs on!
return 0;
}
Your code is leaking memory, since it's allocating the list with malloc() then returning that structure's content by value.
if you want to have a function that returns an empty list by value, you should do just that:
list llinit()
{
list ll;
ll.head = NULL;
ll.tail = NULL;
return ll;
}
The above is just fine, there's no risk of the value "disappearing" due to it going out of scope, this is just as safe as e.g. a function returning a local int value. The return value (all of it!) is copied to the caller's memory as needed.
It's then trivial for the caller to decide whether or not the node should be on the heap or not.
UPDATE: Here is the code on ideone, it really does compile and does not generate an error for the assignment in main().
you have to declare the structure as
typedef struct _list{
list* head; /* could have been struct node* as well */
list* tail;
} list;
Also the list is your custom struture. And the llPushBack() is not a bember of your structure.