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.
Related
Hi everyone I have a problem taking care of a malfunction, I'm building a dynamic linked list which connects structures with *next and *previous,
now if the structures are unable to connect (long story) I need to print "the way does not exist" now I've made an if statement
temp = point_start; // point_start is the head of the list
condition = 2;
for(i=0;i<gagnum;i++) //gagnum is the number of structures
{
temp=point_start->previous; // previous is the pointer of the previous structure.
if (temp != 0xcdcdcdcd) // ------> is this legal?
condition = 1;
else
{
printf("no route found ")
condition = 2;
break;
}
}
I have an if statement which says "if (temp != 0xcdcdcdcd)" so when it gets garbage I put out the message and stop the program, is this legal to use? is there a better way to do this? thank you so much for your help!
Instead of using 0xcdcdcdcd, you should be using 0x0 to indicate a NULL pointer.
Here's a function which does what I think you're trying to do:
// checks to see if the given list is the "first" structure
bool is_first_structure(void* head)
{
return head->previous != NULL;
}
And here's how to use it:
if(!is_first_structure(head))
{
printf("no route found");
}
Hi the answer to the problem is just to NULL all your pointers when you're building the linked list. then check if the pointer is NULL instead of garbage, hope it helps!
Wikipedia writes for 0xcdcdcdcd
Used by Microsoft's C/C++ debug malloc() function to mark uninitialized heap memory, usually returned from HeapAlloc()
So I guess you malloc a node and not initializing the pointers.
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!
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).
I'm getting a SIGTRAP signal when trying to free an dynamically created array, and have no idea on why.
I'm allocating the array like this:
int* visited = (int*) malloc( l.nodeCount * sizeof(int));
(l.nodeCount is an integer. In the instance of the program I get this error, it is set to 12.)
And when I try to free(visited), I get the SIGTRAP signal in the debugger.
The whole function is this one:
int Graph_GetSmallestPathCount(AdjacencyList l, int destination){
//One path if destination is root
if(destination == 0) return 1;
if(l.nodeCount == 0)
return 0;
Queue reading = Queue_NewQueue();
Queue storing = Queue_NewQueue();
/*Allocates visited array*/
int* visited = (int*) calloc( l.nodeCount, sizeof(int));
/*Visited array initialization*/
int i;
for(i = 0; i < l.nodeCount; i++)
visited[i] = 0;
/*Marks root node and enqueues it*/
visited[0] = 1;
Queue_Enqueue(&reading, 0);
//While there are nodes to read
while(!Queue_IsEmpty(reading))
{
//Dequeues a node
int v = Queue_Dequeue(&reading);
//Gets it's adjacency list
List* currentList = AdjacencyList_GetAdjacentNodes(l, v);
listCell* auxCell = currentList->head->next;
//While there are nodes in it's adjacency list
while(auxCell != NULL){
//Enqueues it if it has not been visited
if(visited[auxCell->data] == 0){
Queue_Enqueue(&storing, auxCell->data);
}
//Adds to the paths to that node
visited[auxCell->data] += visited[v];
auxCell = auxCell->next;
}
//When the queue ends
if(Queue_IsEmpty(reading)){
//If the destination has been reached, return
if(visited[destination] > 0){
Queue_Destroy(&reading);
Queue_Destroy(&storing);
return visited[destination];
}
else{
//Switch queues
Queue_Destroy(&reading);
reading = storing;
storing = Queue_NewQueue();
}
}
}
//Destination has not been reached before end of algorithms. Deallocate everything and return 0
free(visited);
Queue_Destroy(&reading);
Queue_Destroy(&storing);
return 0;
}
Sorry for the lack of comments, I did this on a run and didn't put any in. Also sorry for the printf overload, I put them there while trying to pinpoint the problem.
EDIT: I cleaned it up a little.
The weird thing is that the program works for certain inputs and doesn't for others.
Hope someone can help me out =D
I can't tell you why you get a SIGTRAP as you haven't published a minimal example.
However, I can tell you how to find out out yourself:
Make your program readable. Use one instruction per line. The indent tool is your friend. Sure, that won't fix the bug, but it will make it easier for you to find it.
Don't malloc like that. There is no need to cast the return value of malloc, and using calloc(l.nodeCount, sizeof (int)); or similar is more readable anyway.
What SIGTRAP actually means is you've hit a breakpoint instruction. No doubt what's actually happening is that you've jumped to something which is not your code, and might not be code at all, but contains the binary code for a breakpoint. Why did that happen? The normal cause would be memory corruption, particularly stack corruption. I'm guessing free() is corrupting its own stack. And I'd guess the reason for that is because you are (somewhere) writing to memory outside the memory you've allocated. To test this, run your program with the malloc()/calloc() immediately followed by the free() and an exit(0). If that works, you know the issue is something you are doing between.
We can't tell what you are doing between because you haven't (thankfully) posted the full program, but try running it under valgrind. When you get an out-of-range write, valgrind will normally pick it up. Fix every valgrind warning. That doesn't guarantee a solution, but will find one 95% of the time in my experience.
Also note that return visited[destination]; appears to exit the function without free()-ing visited, which is thus a memory leak.
First, don't call malloc() like that. l.nodeCount * sizeof(int) could potentially exceed INT_MAX, and you'll either have a security hole or if you're lucky, a crash.
Instead, use calloc(l.nodeCount, sizeof(int)).
You should also check the return value of malloc or calloc for NULL in the event your program runs out of memory to allocate.
Found the answer. There was indeed a chance that on specific cases the array would be created with one element less than it should. My bad.
Thanks to all who helped =D
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.