Segmentation fault while adding a new node to a list - c

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).

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.

updating a value in main after updating it in a function , without pointers

im trying to update values in main according to what changes were made in a function without using pointers
im working on a snake game and to make a move i send the row and column of both the head and the tail to a void function , and inside of it i change them according to what move was made , but they are not updated in main and therefor the next move wont be donr correctly , how can i update them in main but without using pointers ?(its a homework , they specified not using pointers)
the code below is for one case which is when the player wants to move down (2 is foe down) and at the end i changed the column of the tail and the row of the head, but it dosent update them in main for when i send the next move
if(move==2){
if (board[head_row+1][head_cal] != 0)
{print_finsih_msg(player,ILLEGAL_MOVE);exit(0);}
if(head_row == tail_row && head_cal < tail_cal) {
board[head_row+1][head_cal] = SHTRODEL_HEAD ;
board[head_row][head_cal] = '+' ;
board[tail_row][tail_cal] = 0;
tail_cal--;
head_row++;}
so for examble if the next move is 6 - right it will print that the move is illegal because it still has that the head has its body on the right
C offers three general ways of communicating values back to the calling function:
Returning a value - This is the most common way of providing data back for primitive types. However, you are allowed to make a struct type, and return it to the caller.
Passing a pointer - This is common for situations when multiple variables need to be modified.
Using variables visible to both the caller function and the function being called - these could be static or global variables.
Note that it is not enough to keep a position for the head and the tail of the snake: you need to store all positions occupied by your snake in order to be able to advance its tail to the next step. This could be easily implemented with a Circular Buffer sized at the maximum length of the snake:
static int snake_row[MAX_LENGTH+1];
static int snake_col[MAX_LENGTH+1];
static int snake_head = 0;
static int snake_tail = 0;
Arrays snake_row and snake_col between indexes snake_head and snake_tail represent positions currently occupied by the snake. This makes board[][] optional, because you can check for self-crossing by iterating the buffer.

C Linked list size not limited by malloc

I have created a linked list with the following code. As you can see, I have used malloc to created a list of size 3. But I ran the for loop over size 10 to initialize and print.
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
struct node {
int value;
struct node *next;
};
int main() {
//code
struct node **head;
struct node *curr;
curr = (struct node *) malloc(sizeof(struct node)*3);
head = &curr;
printf("done 1\n");
(*head)->value = 0;
(*head)->next = NULL;
for(int i = 1; i < 10; i++) {
(*head+i-1)->next = (*head+i);
(*head+i)->value = i;
(*head+i)->next = NULL;
}
curr = *head;
printf("done 2\n");
for(int i = 0; i < 10; i++) {
printf("%d\t", (*head + i)->value);
//curr = curr->next;
}
printf("\ndone 3\n");
//free(curr);
return 0;
}
when I compile and run the code, the result obtained is,
done 1
done 2
0 1 2 3 154208560 842282289 876087600 154744882 808859448 875837236
done 3
Why am I able to assign values to the 4th node and access it when I actually created a list of size 3?
I see that garbage values were being printed from 5th to 10th node access. But how is the 4th node being created?
P.S:
I know that 10!=3. The code ran properly when I put the loop in its limits. I wanted to see what will happen when we go out of bounds. I see that the 4th node was also created as I was able to assign value when I actually created a list of size 3.
This is purely to see if I will get seg fault or not.
You're invoking undefined behavior. When you do this, the program may crash, it may appear to work properly, or it might behave in a seemingly random manner.
C doesn't perform any kind of bounds checks on arrays or allocated memory. It's one of the things that makes it fast. What that also means is that it will allow you to do things you're not supposed to do. It trusts the programmer to "do the right thing".
On your particular machine, you see random data after the third element. When I run the same code on my machine, I happen to get the expected output as though enough memory was allocated. Also, if I uncomment the call to free, the program crashes. That's undefined behavior.
Trying to understand undefined behavior is usually a futile effort. It all depends on the implementation details of your compiler and the machine it runs on. In this case, the memory being written to was probably unallocated memory in the heap after the memory that was properly allocated. Depending on how malloc is implemented, that part of memory may contain data needed for malloc and other functions to run properly. The point is that writing past the end of an array does not guarantee a crash, so you need to be careful.
This code will behave differently on the different operating systems.
You may get away even with assigning all 10 integers and print then correctly.
Your code puts the beginning of list on the heap with allocations for only 3 elements.
You may get lucky and use memory for all 10 element or your program will crash on the 4-th!

C Infinite Pointer Loop (Caused By Duplicate Value?)

Compiling with MinGW with -O3 -Wall -c -fmessage-length=0 -std=c99
Well, this is what I think the problem is... Here's the breakdown:
I have a linked list that I built using
typedef struct Coordinate{
int x;
int y;
struct Coordinate *next;
} Coordinate;
I am adding "valid moves" (in the game Reversi/Othello) on a 6x6 board (matrix). My logic for checking whether or not a move is valid or not works just fine - it's adding things to the list that gets me into trouble.
For obvious reasons I want to avoid adding duplicate values to the list. However, every function I attempt to code (that seems like it should work) just crashes the application, segfaulting all the live long day.
So here's a function that I attempted to code:
int inList(Coordinate *list, int x, int y) {
if (list == NULL) return 0;
while (list != NULL) {
if (list->x == x && list->y == y) return 1;
else list = list->next;
}
return 0;
}
and called it like:
Coordinate *validMoves = createNewCoordinate(-1, -1); // Just so that there is *something*
if (!inList(validMoves, 1, 1)) {
validMoves->next = createNewCoordinate(1, 1);
validMoves = validMoves->next;
}
So as far as I know, this should work perfectly. I've looked up examples online and all my really convoluted uses of pointers in this particular program have worked without a hitch thus far.
Anyway, the real problem is that if I don't prevent duplicates from being entered into the same list (connected through pointers), then I get an infinite loop (I imagine this is caused by two elements being considered equal because their non-pointer types are equal).
I've posted all three parts of the code on pastebin for full reference (no worries, open source, man!):
othello.c
othello_engine.c
othello_engine.h
I've tried debugging but I'm not very good at that, I didn't really see anything worth mentioning. Can anyone explain what might be happening and/or give an example of how to avoid duplicates in a linked list? (I've tried so many ways my brain hurts)
EDIT: I do know for a fact that I am getting myself into a cyclical reference because of the following output when I traverse the list later (after multiple valid 'turns' in the game):
{1, 4} {3, 4} {1, 4} {3, 4} {1, 4} {3, 4}
I have no clue how theList = theList->next = theList (pseudo-correct) got in there, perhaps we're in the Matrix...
There is a problem with how you add the new coordinate to the linked list.
validMoves is the pointer to the first Coordinate in your list of valid moves, so initially your linked list looks something like:
validMoves -> [1st_move] -> [2nd_move] -> [3rd_move] -> ... -> [last_move]
And recall that these arrows come from the next pointers stored in the structs (for example, [1st_move]'s next pointer points to [2nd_move], and [last_move]'s next pointer is NULL).
Now let's look at what happens when the code is run which adds the new coordinate to the list (specifically the line marked 2):
if (!inList(validMoves, 1, 1)) {
validMoves->next = createNewCoordinate(1, 1); //2
validMoves = validMoves->next;
}
In line 2, two things happen:
createNewCoordinate(1, 1) allocates a new Coordinate, and then returns you a pointer to said Coordinate, with initial contents set to {1,1,NULL}.
Then, the next pointer of the structure pointed to by validMoves (i.e. [1st_move]'s next pointer) is overwritten, and set to point to this {1,1,NULL} struct.
This leaves your linked list looking something like:
validMoves -> [1st_move] -> [new struct with contents {1,1,NULL}]
??? -> [2nd_move] -> [3rd_move] -> ... -> [last_move]
[1st_move]'s next pointer, which used to point to [2nd_move], now points to your newly made Coordinate, and now nothing points to [2nd_move]! So, the original linked list from [2nd_move] onwards has been orphaned.
gdb can be helpful in debugging such problems. A good starting point would be to add a breakpoint before the suspicious code area, put important variables on your display list (like validMoves, validMoves->next, validMoves->next->next), and then step through execution of the suspicious area and see if the printed values of the variables make sense at each step.
To fix this, we could walk the linked list to the end and then add the pointer to {1,1,NULL} there, but it is easier (and faster) to simply add the new Coordinate at the beginning of the list, but you will need a temp pointer variable, like so:
if (!inList(validMoves, 1, 1)) {
Coordinate *temp = createNewCoordinate(1, 1);
temp->next = validMoves; // the new Coordinate now becomes {1,1,&[1st_move]}
validMoves = temp;
}
Now the newly added Coordinate is at the beginning of the list, the old [1st_move] has been moved to the second position, [2nd_move] to the third, and so on, as required (the linked list is in reverse order of the order they were added in, but I think the order of the elements does not matter in this use case).
Your stated application is for Othello. Why not allocate a contiguous array of size*size chars to store whether a position is a valid move or not, instead of using a linked list?
char * validmoves = malloc(size*size);
This only uses 1 byte of memory per board cell (which you can set to 1 or 0 to indicate whether the move is valid or not), and you don't need to walk a linked list to find out if a move already exists, just navigate to validmoves[(row*size)+col] and check if the byte is set or not; just remember to initialize the array before use.
Happy coding!
EDIT: In my above answer, I assumed your createNewCoordinate function initializes the value of the created struct's next pointer to NULL, but have now noticed that your implementation of it in othello_engine.c leaves it uninitialized. You probably do want to initialize it to NULL.
segmentation fault is usually a dereferenced pointer that is pointing to a bad location (possibly null). Add checks every time you use a pointer value (somthing like if ptr != NULL).
In your code I notice something that looks a bit wrong. When you find a new move to add you assign it:
validMovees->next = createNewCoordinate(x, y);
Then you make the list itsself point to the last node by calling:
validMoves = validMoves->next;
So now your list of validMoves is actually just containing one element (the last one) since it is pointing to the end of the list. You don't want to change validMoves pointer at all, this should always be the start of the list. Instead have another pointer that points to the end of the list, somthing like:
Coordinate *validMoves = createNewCoordinate(-1, -1); // Just so that there is *something*
Coordinate *listEnd = validMoves ;
if (!inList(validMoves, 1, 1)) {
listEnd->next = createNewCoordinate(1, 1);
listEnd = listEnd->next;
}
This may be causing you to infinitly add the same moves?? - not sure without seeing all of your code
----- EDIT -----
Coordinate *validMoves;
Coordinate *listEnd = validMoves;
if (!inList(validMoves, 1, 1))
{
if (validMoves == NULL)
{
validMoves = createNewCoordinate(1, 1); // first time only
listEnd = validMoves;
}
else
{
listEnd->next = createNewCoordinate(1, 1); // add new element to the end
listEnd = listEnd->next; // Move listEnd to last element
}
}
I asked you the data range, so that I can think of some other way to check the duplicate of data. If memory is not a constrained for you. You can do something like the following. This is a logic kind to check the duplicate data value. I have a simple look up table of data value, whose index and value is same and there is a count field. If the count field is zero that means unique value can come in. When you delete the data , subtract the count. This way you keep a track of count and ensure the uniqueness of the value. Since, it is an array no need to traverse also. A few additional code has to implemented for this management. But, It should be possible if well designed.

Keeping track of pointers

I am implementing the standard bubble sort algorithm, and I had a question on pointers.
float *SortValues(float *p, size_t n)
{
float temp;
float didSwap;
float *current;
float *last = &p[n - 1];
float *start = p;
do
{
for (didSwap = 0, current = p; current < last; current++) {
if (current[0] > current[1]) {
temp = current[0];
current[0] = current[1];
current[1] = temp;
didSwap = 1;
}
}
--last;
}
while (didSwap);
return start;
}
I get confused a lot of times using other pointers to point to the start and/or end of the pointer passed in. In something like the code above, I set current to point to p, and start to point to p. The current changes throughout the loop. Since current and p point to the same thing, how does p, and therefore start end up changing to pointing to the same thing as current?
Where start is pointing doesn't change. What start is pointing at does.
Imagine you have five cups and you put a ball in the green one. Then you tell me to replace the ball in the green cup with a dollar bill. Next time you look in the green cup, it will contain a dollar, not the ball you put there.
The last time through the while loop, when last == start, only the initialization of the for loop is executed so that current == p when the while loop exits.
Subscripts vs. Pointers
Right now the code is written with a hybrid approach that uses some subscripting and some pointer addressing.
It's possible that if you rewrote this loop to work entirely with subscripts instead of the current hybrid addressing, then it would be easier to understand.
For that matter, it could be written to use entirely pointers with no subscripts.
I'm not complaining about the current organization which looks just fine, I'm just saying that it might shed some light on the implementation to see it done both ways in pure form.
But to answer your question, keep in mind that the list is always in the same location, it's just that elements have their values swapped. So the beginning of the list is always in the same place, but it doesn't always have the same contents. It's kind of nice that you have such an object-oriented picture embedded in your mind but in this case it is perhaps not serving you so perfectly well. Ultimately, data structures are just arrays of bits at specific addresses...

Resources