Keeping track of pointers - c

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

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.

malloc crashes program on 4th call

I'm making the game atoms in C where people take turns putting atoms into grid spaces. I'm trying to implement a move tracking system wherein every time they make a move, the moves array is increased by one. Not very efficient I know (and I know I don't check malloc return value), but just trying to get it at least working for now. Here's how I'm doing it:
int move_count_temp = (game->move_count)+1;
move_t* moves;
//Check if it's first move
if (game->moves == NULL) moves = (move_t*)malloc(sizeof(move_t*));
else moves = (move_t*)malloc(move_count_temp*sizeof(move_t*));
// Copy old moves over
for (int i=0; i<game->move_count;i++) {
moves[i].x = game->moves[i].x;
moves[i].y = game->moves[i].y;
}
//Copy current move
moves[move_count_temp-1].x = y_coordinate;
moves[move_count_temp-1].y = x_coordinate;
// Free old moves pointer and assign new one
free(game->moves);
game->moves = moves;
game->move_count = move_count_temp;
The problem is on the 4th move it crashes on the 4th line in that sample, when mallocing moves. I've been trying to fix it for a while and just don't know why it's happening. Any insight would help, thanks.
P.S. The game struct has a pointer to a moves struct, and this is the move_t struct;
struct move_t {
int x;
int y;
};
These allocations are wrong:
if (game->moves == NULL) moves = (move_t*)malloc(sizeof(move_t*));
else moves = (move_t*)malloc(move_count_temp*sizeof(move_t*));
You need to allocate space for move_t structures, not pointers to move_t structures. The canonical way to do this helps avoid such mistakes:
if (game->moves == NULL) {
moves = malloc(sizeof *moves);
} else {
moves = malloc(sizeof *moves * move_count_temp);
}
That is, there is no reason to cast the result of calls to malloc() in C, this only serves to clutter the code. And, using an identifier instead of an explicit type in the sizeof operand helps avoid the error in the posted code, as well as making the code easier to maintain.
That said, it seems like the posted code should use realloc() instead of malloc() and free() to reallocate game->moves.

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

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.

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