C Infinite Pointer Loop (Caused By Duplicate Value?) - c

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.

Related

pset4 speller using trie. Problem with the size function

i was working on pset4 speller using trie. i wanted to use recursion to find the size of the dictionary loaded. But nothing is working. According to what debugger is doing, i think that it is probably not returning to what sizer was pointing previously. For example in a dictionary of :
a
aa
aab
ab
the size is able to read the first three. but when i am returning the counter to the previous size, it does not read the letter b after a. I think it is still checking the array in which it is reading aab. what can i do ???
unsigned int size(void)
{
int ctr = 0;
for (int i = 0; i < N; i++)
{
if (sizer -> children[i] == NULL)
{
continue;
}
else
{
// do i need to use a pointer here to point
// to sizer before changing it
sizer = sizer -> children[i];
if ((sizer -> is_word) == true)
{
ctr ++;
}
int x = size();
ctr += x;
}
}
// Before returning ctr should i use the pointer to change sizer to
// what it was previously . Can it work???
return ctr;
}
I think it is still checking the array in which it is reading aab. what can i do ???
I think you're right.
Consider how you update the value of global variable sizer in this code. The only way you ever do that is this:
sizer = sizer -> children[i];
Since you only ever set sizer to point to one of the children of the current node, never restoring it to a previous value, the program follows exactly one path from the root to a leaf, and then it's exhausted its capabilities. With different inputs you can demonstrate for yourself that this is what is happening. For example,
a
b
ba
will report a count of 1, since it traverses node "a" first, and it's a leaf.
Global variables can very easily get you into trouble, especially modifiable ones. Start now cultivating a habit of avoiding their use. Prefer to convey information to functions via arguments, instead.
Also prefer to avoid recursion under most circumstances, and don't even consider combining recursion with modifiable global variables until you have a lot more experience (which at that point will tell you "I want no part of that").
It's unclear what is the type of sizer, but suppose it is struct sizer *. In that case, consider what other changes would be needed to change the function signature to
unsigned int size(const struct sizer *node_sizer);
That's not just a style thing. Done properly, it will resolve your functional issue, too.

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.

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

how do i delete arrays of typedef structs?

I am trying to delete an array of initialized structs e.g. reset the array
My struct:
struct entry{
char name[NAME_SIZE];
int mark;
};
typedef struct entry Acct;
Acct dism2A03[MAX_ENTRY];
Acct clear[0]; << temp struct to set original struct to null
My attempt:
entry_total keeps track of how many structs in the struct array dism2A03[x] have values set in them.
I tried to create an empty array of the same struct clear[0]. Looped through initialized arrays in dism2A03[x] and set them to clear[0]
for(m=0;m<entry_total;m++){
dism2A03[m]=clear[0];
}
break;
However, it is setting them to 0, i want them to become uninitialized e.g. no values in them
You cannot have memory with no value in it. It's physically impossible. It's due to the laws of physics of our universe :-)
Also, this:
Acct clear[0];
is wrong. You cannot have an array with zero elements. Some compilers will allow this as an extension, but it's not valid C. And for the compilers that allow this, it doesn't do what you think it does.
It would seem to me that what you want instead is to resize the array. To do that, you would need to copy the elements you want to keep into a new array, and then free() the old one. To do that, you need to create dism2A03 using dynamic memory:
Acct *dism2A03 = malloc(sizeof(Acct) * MAX_ENTRY);
if (dism2A03 == NULL) {
// Error: We're out of memory.
}
(malloc() returns NULL if there's no more free memory, and the code checks that. Usually all you can do if this happens is terminate the program.)
When you want a new array with some elements removed, then you should back up the starting address of the current one:
Acct* oldArray = dism2A03;
then create a new one with the new size you want:
dism2A03 = malloc(sizeof(Acct) * NEW_SIZE);
if (dism2A03 == NULL) {
// Error: We're out of memory.
}
copy the elements you want from the old array (oldArray) to the new one (dism2A03) - which is up to you, I don't know which ones you want to keep - and after than you must free the old array:
free(oldArray);
As a final note, you might actually not want to create a new array at all. Instead, you could keep having your original, statically allocated array ("statically allocated" means you're not using malloc()):
Acct dism2A03[MAX_ENTRY];
and have a index variable where you keep track of how many useful elements are actually in that array. At first, there are 0:
size_t dism2A03_size = 0;
As you add elements to that array, you do that at the position given by dism2A03_size:
dism2A03[dism2A03_size] = <something>
++dism2A03_size; // Now there's one more in there, so remember that.
While doing so, you need to make sure that dism2A03_size does not grow larger than the maximum capacity of the array, which is MAX_ENTRY in your case. So the above would become:
if (dism2A03_size < MAX_SIZE) {
dism2A03[dism2A03_size] = <something>
++dism2A03_size; // Now there's one more in there, so remember that.
} else {
// Error: the array is full.
}
As you can see, adding something to the end of the array is rather easy. Removing something from the end of the array is just as easy; you just decrement dism2A03_size by one. However, "removing" something from the middle of the array means copying all following elements by one position to the left:
for (size_t i = elem_to_remove + 1; i < dism2A03_size; ++i) {
dism2A03[i - 1] = dism2A03[i];
}
--dism2A03_size; // Remember the new size, since we removed one.
Note that you should not attempt to remove an element if the array is empty (meaning when dism2A03_size == 0.)
There's also the case of adding a new elements in the middle of the array rather than at the end. But I hope that now you can figure that out on your own, since it basically a reversed version of the element removal case.
Also note that instead of copying elements manually one by one in a for loop, you can use the memcpy() function instead, which will do the copying faster. But I went with the loop here so that the logic of it all is more obvious (hopefully.)
when you declare an array in this way Acct dism2A03[MAX_ENTRY]; the array is allocated in the stack, therefore it will be removed when the function will perform the return statement.
What you can do is to allocate the structure in the heap via malloc/calloc, and then you can free that memory area via the free function.
For example :
typedef struct entry Acct;
Acct * dism2A03 = calloc(MAX_ENTRY, sizeof( struct entry));
// ....
free(dism2A03);

How to _delete_ element from dynamic array?

I have seen other answers to questions like this, but none seemed to work for me. Say I have a dynamic array:
int* myarray;
myarray = malloc(myarray, 4*sizeof(int));
myarray[0] = 1;
myarray[1] = 2;
myarray[2] = 3;
myarray[3] = 4;
What I want to do is to remove (and free, because the array will keep on getting larger and larger) the first element of the array. I am well aware of realloc which removes the last element of the array if shrunk. Any ideas on this? Is this possible?
Thanks in advance!
One method I can think of is doing
memmove(myarray, myarray+1, 3*sizeof(int))
and then use realloc to shrink the array. I'm not sure there are more efficient ways to do this in C.
You have to shunt all the other elements along one. Conceptually, it's like this:
for( int i = 0; i < 3; i++ ) p[i] = p[i+1];
As others have mentioned, memmove is optimized for shifting memory segments that overlap, rather than using the above loop.
Moving data around is still inefficient as your array grows larger. Reallocating an array every time you add an item is even worse. General advice is don't do it. Just keep track of how large your array is and how many items are currently stored in it. When you grow it, grow it by a significant amount (typically you would double the size).
It sounds like you might want a circular queue, where you preallocate the array, and a head and tail pointer chase each other round and round as you push and pop items on.
Typically a "Delete" operation is not possible on an array. Perhaps you want to create and use a linked list?
C++ has its std::vector which supports this. What it would do is to shift elements that come later, forward by 1 element. You could implement this, and call realloc later.
Storing them in reverse is an obvious workaround if only first element needs to be deleted.
I don't think that you'll find a proper/clean way to do that in C. C++ as some lybraries who do that, and almost all the OO oriented languages can do that, but not C. All I can think of is moving memory and, yes, calling realloc, or setting the position you want to free to a known value wich you'll consider empty in a memory re-use policy.
Another way to turn the problem is by a dynamic implementation of the array. DOn't know if you want to go there, but if you do, here's some brief example.
Since you're only saving integers, a struct like this:
typedef struct DynamicArray_st{
int x;
struct DynamicArray_st *next;
}DynamicArray;
Makes it possible to alloc and free elements as the program needs to. It also allows insertion in the middle, begin or end and the same for frees.
The way you'll do it is by saving a pointer to the begin of this dynamic type and then iterate over it.
The problem is that you can't access data by the [] notation. Iterations are necessary wich makes it heavier on processing time.
Besides that, your code would become something like this:
DynamicArray *array = malloc(sizeof(DynamicArray)); /*Just a first element that will stay empty so your Dynamic array persists*/
array->next = NULL;
DynamicArray *aux = array;
DynamicArray *new;
for(i = 0; i<4; i++){
new = malloc(sizeof(DynamicArray));
new->next = NULL;
new->x = i+1;
aux->next = new;
aux = new;
}
Here you have a sequence of structs in a way that each struct points to the next one and has a integer inside.
If now you'd do something like:
aux = array->next; /*array points to that empty one, must be the next*/
while(aux != NULL){
printf("%d\n",aux->x);
aux = aux->next;
}
You'll get the output:
1
2
3
4
And freeing the first element is as easy as:
aux = array->next;
array->next = aux->next;
free(aux);
If you try to draw it(structs are boxes and next/aux/next are arrows) you'll see one boxe's arrow outline an box - the one you want to free.
Hope this helps.

Resources