Copying data between two struct pointers giving segmentation fault - c

I am getting a segmentation fault when trying to copy the contains of a pointer to a struct to another pointer.
My struct:
typedef struct State {
char alphabets[2][6];
struct State *PREV; /*this points to the previous state it came from*/
struct State *NEXT; /*this points to the next state in the linked list*/
int cost; /*Number of moves done to get to this position*/
int zero_index;/*this holds the index to the empty postion*/
char *move[2];/*this holds the move that was done to get to this state*/
} State;
Memory allocation method:
State *memAllocator() {
State *p = (State*)malloc(sizeof(State));
if (p == NULL) {
printf("Malloc for a new position failed");
exit(1);
}
return p;
}
Here' an example of my Structs Alphabets
CANAMA
PANAL_
I have a randomize function that gives me the two possible moves of the state. The two moves for the above state would be
CANAM_
PANALA
AND
CANAMA
PANA_L
In my randomize state function I copy the contains of my current state and then put it in the new state.
But here is the problem, I'm doing a breadth first search and trying to find out the shortest distance from the one state to another. In the process of doing I get pretty far in the search. But then it gives a segmentation fault at line where I copy the contains of current state to a new state.
I tried memcpy as well, but it gives the same segmentation fault. Here are the lines:
*new_state=*current_state;
/*memcpy(new_state, current_state, sizeof(State));*/
So, is the way I am copying my memory incorrect that is causing the problem. But if thats the case then why does it go for a while and then gives out a segmentation fault. Please help.
Here's a link to my full code. Full Code

Looks like at least one of new_state and current_state is null. Best to change your printfs from printf("If exception below then problem in swapN\n"); to printf("If exception below then problem in swapN: %p %p\n", current_state, new_state1); to see where this happens; but at least one possibility is the following:
printf("If exception below then problem in swap3\n");
new_state1 = swap(empty_index/10, (empty_index%10)-1,current_sta te, new_state1);
printf("If this prints problem not in swap\n");
if (new_state1 != NULL){
//... [REMOVED FOR CLARITY]
return;
}
/*Go East*/
/*printf("Step %d, move %c west\n",current_state->alphabets[empt y_index/10][(empty_index%10)+1]);*/
printf("If exception below then problem in swap4\n");
new_state1 = swap(empty_index/10, (empty_index%10+1),current_state, new_state1);
Notice that the second call to swap() will ALWAYS have new_state1 be NULL (because you already returned it if's not null!)

Related

Singly Linked List EXC_BAD_ACCESS

I'm trying to write a remove function for a singly linked list and got this error message:
Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
What does this message mean and how shall I fix it?
void fifoqueue_remove(Fifoqueue_Ptr queue_ptr, void * this_call){
Queue_Container_Ptr position = queue_ptr->front_ptr; //make position head
while (position->next_ptr != NULL){
if (position->next_ptr->content_ptr == this_call){
Queue_Container_Ptr next = position->next_ptr;
position->next_ptr = next->next_ptr;
free((char*) position); //remove position
}
else{
position = position->next_ptr;
}
}
}
Your loop is doing bad things with position which, if not the actual issue, is definitely undesirable.
As currently written, if you find the value to remove, you are calling free(position); and then continuing the loop. The very next thing that will happen is you access position->next_ptr, dereferencing a memory address that you returned to the system only moments ago.
This is likely to result in a crash if you're lucky. Possibly you're compiling in non-optimized mode where the memory manager is writing a byte pattern over any freed memory, so that attempts to use it are far more likely to result in bad pointer access.
I see you have actually prepared for the "correct approach" here but forgotten to do it:
// You remembered to save position->next_ptr
Queue_Container_Ptr next = position->next_ptr;
// ...
free(position);
// But you forgot to do this:
position = next;
It should also be mentioned that you are not handling the very last element in the list. Or perhaps that's not necessary because your list has a dummy tail node or something. It's hard to be sure, given what you've shown. But you should make sure that you test removal of a value that is the last position. You might discover a bug there.

Segmentation Fault on calling a function

When I call the print_linklist function I am getting a segmentation fault. Here is the function definition:
//will display the node in a nice string
char * term_to_string(term_t * term){
int exp = term->exponent;
int coef = term->coefficient;
return ("%dx^%d", coef, exp);
}
**//will print the list using the nodde_to_string method
void print_linklist(node_t * curr){
printf("entering print to list!!!");
node_t * current = curr;
while(current != NULL){
printf("%s +", term_to_string(curr->term));
current = current->next_node;
}
}**
And here is the main method where it is being called:
/* This is your main file */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"common.h"
#include"buildlinklist.h"
#include"printandcombine.h"
int main() {
node_t * node_ptr = NULL;
node_t * new_node_ptr=NULL;
printf("NAME: SAMPLE OUTPUT\n");
/* Build linklist */
read_objects(&node_ptr);
/* Print the link list */
printf("Original: \n");
print_linklist(node_ptr);
/* Combine like terms in the link list and craeate a new link list */
new_node_ptr=combine_like_terms(node_ptr);
printf("\nCombined: : ");
/* Print new combine linklist */
print_linklist(new_node_ptr);
printf("\nNAME: SAMPLE OUTPUT\n");
free(node_ptr);
free(new_node_ptr);
return 0;
}
After the function is called I get "zsh: segmentation fault ./project1". I don't even get the "entering print to list!!!" to print from the print_linklist method.
return ("%dx^%d", coef, exp);
That's not doing what you seem to think it's doing (what I think you think it's doing is to return a string created by some sort of printf functionality).
However, the comma operator in something like a, b evaluates both a and b, but the result is b. The n-variant, like a, b, c, d, evaluates everything and returns the last one (d).
Hence you are returning exp as if it was a character pointer. It almost certainly isn't (since you're trying to printf it with %d) so, if you treat it as such, hilarity may ensue.
Well, less hilarity and more crashing/weirdness, but you get the idea :-)
You could create strings in heap memory and pass them around but it's sometimes difficult for newcomers to the language to do that safely. Instead, I would suggest simply printing the thing within the function, with something like:
void print_term(const term_t *term, const char *after){
printf("%dx^%d%s", term->coefficient, term->exponent, after);
}
void print_linklist(node_t *curr){
puts("entering print to list!!!");
node_t *current = curr;
while (current != NULL){
print_term(curr->term, " +");
current = current->next_node;
}
}
You'll notice my "entering print to list" statement is subtly different to yours in that it uses puts, which appends a newline character to the end (you could do that explicitly, with \n, if you wanted to stick with printf).
Since standard output is line-buffered for terminal devices, the reason you're not seeing that is almost certainly due to the fact your code is crashing (as per this answer) before it flushes. In that case, unflushed data is likely to just disappear.
There could be a number of reasons you are getting a segmentation fault but trying to print the list is not one of them. If your read_objects() declaration is like this read_objects(node_t * curr) then you shouldn't pass as an argument the address of the pointer
read_objects(&node_ptr);
This should be read_objects(node_ptr);
Also, if you want to iterate through the list and print it you should create a pointer to the head of the list in the main() function node_t *head = NULL;
and pass it as a parameter in the print_linklist(head);.
After that, make *current point at the head of the list node_t * current = head;.
That way you are starting printing the nodes from the start. You should also check if the list is empty.
I don't even get the "entering print to list!!!" to print from the print_linklist method.
printf doesn't cause anything to be printed to the screen. It just copies a string into a buffer to be printed at some later time. If you want to force the buffer to be printed, you can call fflush. As mentioned in comments, if stdout is directed to an interactive device, including a \n in the output string will generally also cause the buffer to be flushed to the actual output device.
After the function is called I get "zsh: segmentation fault ./project1".
This probably happens in term_to_string if you call it with an invalid pointer argument, when it tries to dereference its argument.

history in implementation of shell get segmentation fault

So I wrote some code to implement the shell (Linux, GCC, C language) and it all works but from some reason the code crashes when I added the history option:
It really doesn't (the other code) so I'll put here only what you need.
The problem is when I type quit after one old command that need to be saved in the history and when I type quit it just crushes with segmentation fault (core dumped).
The history is saved in a structure of a linked list, string of command and the node for the next node, also I saved the head in the main. The point is that I want to save only 15 last commands, and I don't care about the others, so every time I want to print the list I just moved on the first 15 nodes in the loop.
When I debugged with GDB I saw that the line the code crashes is the line after he add the first command the the history but the current line is really not related to the history:
main:
int main()
{
history_ll* top;
char userInput [CHOICE_LENGTH];
char buff[PATH_MAX];
int flag=1;
cmdLine * head;
while (flag)
{
getcwd(buff, PATH_MAX);
printf("%s:~$ ",buff);
fgets(userInput,MAX_INPUT, stdin);
userInput[strlen(userInput)-1]=0;
historyAdder(userInput,&top);
if(strcmp(userInput,QUIT_OPTION)==0) //segmentation fault here!
{
flag=0;
}
else
{
//doesn't matter
}
}
return 0;
}
the historyAdder looks like this:
void historyAdder(const char *command,history_ll** top)
{
history_ll* node;
strcpy(node->command,command);
node->command[strlen(command)]=0;
if(historyLength!=0)
{
node->next= *top;
}
else
{
node->next= NULL;
}
*top = node;
historyLength++;
}
NOTE: historyLength is a global variable
This is the structure:
typedef struct history_ll{
char command[CHOICE_LENGTH];
struct history_ll *next;
}history_ll;
Thank you helpers!
There are at least two important issues in this code.
One is that buffer length might ne too short when you read from stdin:
definition:
char userInput [CHOICE_LENGTH];
but usage is:
fgets(userInput,MAX_INPUT, stdin);
You should use same buffer size or assert MAX_INPUT is less or equal CHOICE_LENGTH.
Second, you trigger undefined behavior by dereferencing uninitialised pointer here:
void historyAdder(const char *command,history_ll** top)
{
history_ll* node;
strcpy(node->command,command); /* bad... */
Here (and in the lines following)
void historyAdder(const char *command,history_ll** top)
{
history_ll* node;
strcpy(node->command,command);
...
the code dereferences an uninitialised pointer: node Doing so invokes UB and mostly likely crashes the program.
This is probably your problem:
char userInput [CHOICE_LENGTH];
...
fgets(userInput,MAX_INPUT, stdin);
Unless CHOICE_LENGTH is greater than or equal to MAX_INPUT, fgets can write past the end of the userInput array, which will corrupt memory, leading to a crash. However, since you did not show a complete program that I could compile for myself and watch crash, I can't be sure.
Two pieces of advice for you:
You're on Linux, so you have getline. Use it instead of fgets and you won't have to worry about input buffer sizes.
Whenever you have a program that is crashing with segmentation faults, the first thing you reach for should be valgrind. Very often, valgrind will reveal that the real bug is nowhere near where you thought it was.

Segmentation fault while adding a new node to a list

i have a problem while searching a list and trying to add a new node.
The Code looks as follows
struct sizelist{
int currentsize, origsize;
struct sizelist * next;
};
typedef struct sizelist item;
Here are sizes the content, items is the amount of nodes connected and next is the next node.
void firstfit(item tosort){
int junksize = tosort.currentsize;
int paired;
item* current;
for(int i=0;i<containeramount;i++){
if(containers[i].currentsize - junksize >=0){
paired = i;
break;
}
}
current = &containers[paired];
while(current->next!=NULL){
current = current->next;
}
containers[paired].currentsize = containers[paired].currentsize - junksize;
current->next = &tosort;
}
containers is an array of item.
This seems to work now. But now i have a problem with my output:
void writeout(){
item* current;
for(int i=0;i<containeramount;i++){
current = &containers[i];
for(int j=0;; j++){
printf("%d ",current->currentsize);
if(current->next!=NULL){
current = current->next;
}
else{
break;
}
}
printf("\n");
}
}
Now you also have all to understand the program.
I give it for example 3 containers of size 10 each and things to sort of size 6,8,1,5. It looks like firstfit makes it's job, but the writeout method not.
The proper output here should be:
10 6 1
10 8
10 5
Here the output for origsize is:
10 3
10 3
10 3
and for currentsize it is:
3 134515941
2 134515941
5 134515941
It looks like the latest revision of the code is much improved,
but tosort is passed into firstfit(item tosort) by value.
That means within the function firstfit(item tosort), tosort is a temporary
variable that is destroyed at the end of the function.
(This was in the earlier version of the program too, but we looked
at other problems first.)
Now that the function is doing its work on the actual contents
of containers[paired] rather than on a temporary copy of something,
the final next pointer in the list is being set (as desired),
but it points to the temporary object tosort.
When the function ends, tosort goes out of scope.
Presumably, something else gets written to the same block of virtual
memory by the time you try to print this out.
This will work better if the function is changed to
firstfit(item* tosort), that is, pass a pointer instead of a copy of
the struct.
This will behave a little bit more like you would expect a call to a function
to behave in Java.
Note: The remarks below refer to revision 2 of the question.
The code in the question has since been modified so that it follows
these recommendations.
I'm finding so many apparent errors in the code it's hard to keep track
of all of them, but I suspect that the segmentation fault is here:
current = containers[paired];
for(int i=0;i<containers[paired].items;i++){
current = *current.next;
}
One of the errors in the code is that you declare item current;.
That means current is always a temporary data structure and is never
actually "in" containers[paired]. When you do current.next = &tosort; the only thing that is changed is a field of this temporary data structure, which goes out of scope on the next line and is destroyed. So in effect that line does nothing at all. It most decidedly does not insert any data in containers[paired].
On the other hand, containers[paired].items++; does increment the counter in containers[paired]. So now containers[paired].items is greater than the number of items actually in the linked list. This means that when you come into this function some other time and execute the loop above with the same containers[paired], you will execute current = *current.next; too many times; you end up trying to access the next node of the last node in the list, and then you segfault.
The standard way to implement a simple linked list in C is to set
the next pointer to 0 (or NULL if it's defined as 0) whenever
there is no actual "next" thing in the list; the last thing in the list
always has next equal to 0. In order to find the last thing in the list,
you don't count the number of times to follow the next pointer;
you simply follow the next pointer until you reach the node whose
next pointer is 0, and then you stop.
I highly recommend getting rid of items. You can always find out how many items are in the container by following the list to the end and counting the number of nodes you encounter. Sure, this takes longer than just reading the value of items, but it will give you the correct answer and it will not cause a segmentation fault. Get your program to work without error, and then you can think about making it faster if you need to (for example by putting items back in your struct and making it actually have the correct value).

Segmentation fault occuring in C but empty case is handled

I am trying to create a sorted linked_list repository in the most efficient way possible in C. The linked list will store data records that contain a "key" and a "data" value. The linked list should keep the records sorted by key. An example linked list would look like {1, 5}, {3, 8}, {4, 7}. The linked list keeps the records sorted by key.
I have a function called "invert" which adds a value to the list only if a record with the same key value does not already exist in the list. If the key is found in the list, it should remove the record. I already have functional code for all of this, but now I'm trying to make it more efficient, so I modified my code in order to reduce the number of iterations of the program. For some reason though, in my new code, I'm getting a segmentation fault. Furthermore, when I added print statements to debug, the print statements would not print unless I added the newline character to the end of the statements. Here is the code:
node *pnode;
printf("made pnode\n");
node *delTemp;
printf("made delTemp\n");
node *travTemp;
printf("made travTemp\n");
travTemp = &sentinel; //sentinel is an empty node that is always
// present in the linked list but is not an actual record. It is just there
// to make insert and deletion easier
while((travTemp->next)!=NULL && (travTemp->next->key)<key){
printf("inside while loop\n");
travTemp = travTemp->next;
}
if((travTemp->next->key)==key){
printf("deleting\n");
delTemp = travTemp->next;
travTemp->next = delTemp->next;
free(delTemp);
return 0;
}
printf("outside while loop \n");
pnode = malloc(sizeof(node));
pnode->data = data;
pnode->key = key;
pnode->next = travTemp->next;
travTemp->next = pnode;
return 1;
For some reason, neither "inside while loop" nor "outside while loop" will print. I wrote a quick if statement to see whether travTemp->next is null, which it should be at the beginning of the program. However, in that case, it should still print "outside while loop" shouldn't it? I am very confused as to where the segmentation fault is occurring. Thanks in advance for any help. Also, does anyone have any explanation as to why the print statements in the very beginning of the code would not print out unless I added "\n" to it?
Also, sentinel is defined as follows:
node sentinel;
void Repository_init(){
sentinel.data = -1;
sentinel.next = NULL;
sentinel.key = -1;
}
Repository_init() is called in main() without a problem.
EDIT:
I used a debugger and found that the seg fault is coming in at the statement "if ((travTemp->next->key)==key)". I can understand why this would occur at the start of the program, but I'm not sure how to overcome that. Putting an if statement around that if statement to check if travTemp is not NULL seems redundant.
Segmentation fault is occuring due to
if((travTemp->next->key)==key){
when
travTemp->next == NULL
In this case both prints inside while loop and outside while will not be printed.

Resources