pset4 speller using trie. Problem with the size function - c

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.

Related

Initialising member elements of a dynamically allocated array of structs to zero

I have had a look around but have not been able to find an answer to this question already. I am trying to create a hash table of which each element is a struct. In each struct is a variable to let the program know if the cell has been occupied, for this to work I need to set all of them to zero. The thing is it worked fine but now and then (seemingly randomly) I'd get an access violation. I thought I fixed it but when I come to grow my array the error creeps up again, leading me to believe that I have made an error. My pointer knowledge is not that good at all, so any help would be appreciated. This is what the function looks like:
HashTableCell *initialiseTable(HashTableCell *hashTable, int *tableSizePtr)
{
int i = 0;
int totalSize = *tableSizePtr * sizeof(HashTableCell);
HashTableCell *tempStartingcell;
tempStartingcell = (HashTableCell*)malloc(sizeof(HashTableCell));
*tempStartingcell = *hashTable;
while (i <= *tableSizePtr)
{
/*we keep moving forward, need to use the first entry*/
*hashTable = *(tempStartingcell + (i * sizeof(HashTableCell)));
hashTable->isOccupied = 0;
i++;
}
free(tempStartingcell);
return hashTable;
}
And before I malloced some space for the table and passed it in another function like so:
HashTableCell *hashTable;
hashTable = (HashTableCell*)malloc((sizeof(HashTableCell)*tableSize));
hashTable = initialiseTable(hashTable, tableSizePtr);
The idea is to start at the beginning and move along the correct number of spaces along per iteration of the while loop. When I come to resize I merely make a new array with double the malloced space and pass it to the initialise function but this throws up an access violation error at seemingly random indexes.
I am using VS2015 if that helps anything.
Thank you for your help.
The problem is in this line:
*hashTable = *(tempStartingcell + (i * sizeof(HashTableCell)));
When you are adding an integer to a pointer, C and C++ already take into account the size of the array elements, so you should not multiply with sizeof(HashTableCell), but rather do:
*hashTable = *(tempStartingcell + i);
Otherwise, your extra multiplication will cause an access outside of the tempStartingCell array. It makes even more sense to write it like this:
*hashTable = tempStartingcell[i];
But there is more wrong with your code; if you just want to set isOccupied to zero for each element in hashTable, just do:
void initialiseTable(HashTableCell *hashTable, int tableSize)
{
for (int i = 0; i < tableSize; i++)
hashTable[i].isOccupied = 0;
}

Uninitialised array using malloc()

It was, actually, the display function after all. Sorry if I wasted your time (I didn't actually put the code of the display function here, my bad. However, I did learn some new things, so thank you all!
I have created a structure which involves an array that represents a set of integers.
When I first create a structure, I use malloc() to allocate space for the structure and thus, the array.
The problem resides, however, in the fact that when I create the structure, the first element of the array is being assigned a number. I want, however, to just create a structure where the array in it is uninitialised.
typedef struct set{
int numberOfValues; /* The number of values in the set */
int value[40]; /* the set */
} *Set; /* Set is thus a pointer to struct set */
Set aOfPStructs[4];
void create()
{
static int setnum = 0;
Set S; /* S is a pointer to struct set */
if (setnum <= 4)
{
S = (struct set *) malloc(sizeof(struct set));
S->numberOfValues = 0;
aOfPStructs[setnum] = S;
printf("The set's number is %d\n", setnum);
setnum++;
}
else
printf("Error. No more sets can be created.\n");
}
The above is only a snippet from the whole program, but any other code is irrelevant to the question tbh.
So with that code, if I were to display the contents of the array in the structure, I would get 1 value. Thing is, I have not added any elements to the array, so I should get no values at this point. Can I fix this?
Any help would be appreciated! Thanks!
Edit:
I tried memset(), but it's not exactly what I want. When I use the create(), I want 0 elements in the array value[], but the code is generating 1 random element once I use the create function.
The function. to display the element seems to work just fine though. Funny thing is, when I run a function to delete one element from the array, that extra element is removed, only to be added again if I run the add() function.
Edit 2:
Added a screenshot for further explanation of my problem. I appreciate every comment thus far, and future ones too.
http://imgur.com/cza3ip6
Edit 3:
Ok, I get the use of memset() now and the concept of initialisation. Thing is, if I wanted to check the number of elements of the set, just right after I create it, I should get 0 because I have not added any elements, but an element is being generated with create...
I think you may not understand what "initialized" and "uninitialized" mean.
"Uninitialized" means "holding whatever bit pattern happens to be left over from the last computation that used this memory or from bootstrapping the machine."
"Initialized" just means you have assigned a set value.
The malloc call gives you uninitialized storage according to this definition. So what you are seeing is the best you can get. You are printing the integer formed from the arbitrary bit pattern in the first array slot.
For what it's worth, the simplest way to get a pre-zeroed memory block of n ints (initialized to zero) is to say.
int *blk = calloc(n, sizeof(int));
Use memset to set to 0 all the data in the structure. By default when you use malloc the memory you get is not initiliazed:
S = (struct set *) malloc(sizeof(struct set));
memset(S, 0, sizeof(struct set));
Try this. It uses a little different approach to create and initialize array of structs, but the relevant point is that it uses memset to init array of ints for each element of struct array:
#include<stdio.h>
typedef struct {
int numberOfValues; /* The number of values in the set */
int value[40]; /* the set */
}SET;
SET set[4], *pSet; //initialize SET *, pSet to the first position of set
main()
{
int i;
pSet= &set[0];
for(i=0;i<4;i++)
{
memset(pSet[i].value, 0, sizeof(int)*40); //set all elements of member value to 0
}
}
You haven't posted the function displaying your set. I suppose that the problem may be there. Maybe you use something like for(i=0; i <= S->numberOfValues; i++) instead of for(i=0; i < S->numberOfValues; i++), so you print the first element even if not there.

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.

Recursive struct and malloc()

I have a recursive struct which is:
typedef struct dict dict;
struct dict {
dict *children[M];
list *words[M];
};
Initialized this way:
dict *d = malloc(sizeof(dict));
bzero(d, sizeof(dict));
I would like to know what bzero() exactly does here, and how can I malloc() recursively for children.
Edit: This is how I would like to be able to malloc() the children and words:
void dict_insert(dict *d, char *signature, unsigned int current_letter, char *w) {
int occur;
occur = (int) signature[current_letter];
if (current_letter == LAST_LETTER) {
printf("word found : %s!\n",w);
list_print(d->words[occur]);
char *new;
new = malloc(strlen(w) + 1);
strcpy(new, w);
list_append(d->words[occur],new);
list_print(d->words[occur]);
}
else {
d = d->children[occur];
dict_insert(d,signature,current_letter+1,w);
}
}
bzero(3) initializes the memory to zero. It's equivalent to calling memset(3) with a second parameter of 0. In this case, it initializes all of the member variables to null pointers. bzero is considered deprecated, so you should replace uses of it with memset; alternatively, you can just call calloc(3) instead of malloc, which automatically zeroes out the returned memory for you upon success.
You should not use either of the two casts you have written—in C, a void* pointer can be implicitly cast to any other pointer type, and any pointer type can be implicitly cast to void*. malloc returns a void*, so you can just assign it to your dict *d variable without a cast. Similarly, the first parameter of bzero is a void*, so you can just pass it your d variable directly without a cast.
To understand recursion, you must first understand recursion. Make sure you have an appropriate base case if you want to avoid allocating memory infinitely.
In general, when you are unsure what the compiler is generating for you, it is a good idea to use a printf to report the size of the struct. In this case, the size of dict should be 2 * M * the size of a pointer. In this case, bzero will fill a dict with zeros. In other words, all M elements of the children and words arrays will be zero.
To initialize the structure, I recommend creating a function that takes a pointer to a dict and mallocs each child and then calls itself to initialize it:
void init_dict(dict* d)
{
int i;
for (i = 0; i < M; i++)
{
d->children[i] = malloc(sizeof(dict));
init_dict(d->children[i]);
/* initialize the words elements, too */
}
}
+1 to you if you can see why this code won't work as is. (Hint: it has an infinite recursion bug and needs a rule that tells it how deep the children tree needs to be so it can stop recursing.)
bzero just zeros the memory. bzero(addr, size) is essentially equivalent to memset(addr, 0, size). As to why you'd use it, from what I've seen around half the time it's used, it's just because somebody though zeroing the memory seemed like a good idea, even though it didn't really accomplish anything. In this case, it looks like the effect would be to set some pointers to NULL (though it's not entirely portable for that purpose).
To allocate recursively, you'd basically just keep track of a current depth, and allocate child nodes until you reached the desired depth. Code something on this order would do the job:
void alloc_tree(dict **root, size_t depth) {
int i;
if (depth == 0) {
(*root) = NULL;
return;
}
(*root) = malloc(sizeof(**root));
for (i=0; i<M; i++)
alloc_tree((*root)->children+i, depth-1);
}
I should add that I can't quite imagine doing recursive allocation like this though. In a typical case, you insert data, and allocate new nodes as needed to hold the data. The exact details of that will vary depending on whether (and if so how) you're keeping the tree balanced. For a multi-way tree like this, it's fairly common to use some B-tree variant, in which case the code I've given above won't normally apply at all -- with a B-tree, you fill a node, and when it's reached its limit, you split it in half and promote the middle item to the parent node. You allocate a new node when this reaches the top of the tree, and the root node is already full.

Pointer assignment to dynamic array of structs

Basically all I am trying to do is assign something (a Polynomial) to a dynamic array at a given index, overwriting whatever is there. For simplicity I just made subtract() return a pointer to the first element in the polynomialArray. So, this code should copy the contents of the first element and replace another element (I know that a deep copy is necessary, and that is implemented in subtract). I have been spoiled by java (and you kind folks)...
When I go to print it at the index at which it is copied to, there is nothing there.
Usually something like Poly1 = 2x^3 + 4x would print, but instead it just prints Poly1 =.
Compiles fine and runs, but does not do what I need it to. EDIT: Runs fine if there wasn't anything at that index. If there is something at the index, seg fault.
//Portion of main from another file
Polynomial* subtracted = subtract(op1_index, op2_index);
insert(subtracted, diff_index);
printPolynomial(diff_index);
//Methods in question (utils file)
void insert(Polynomial* element, int index) {
if(index > num_polynomial) {
polynomialArray = (Polynomial*)realloc(polynomialArray, (index + 1) * sizeof(Polynomial));
}
free(polynomialArray[index].polynomialTerm);
polynomialArray[index] = *element; // Problem here?
}
Polynomial* subtract(int op1_index, int op2_index) {
return &polynomialArray[0];
}
//Typedefs accessible in main and utils file
typedef struct term {
int exponent;
int coefficient;
} Term;
typedef struct polynomial {
Term *polynomialTerm;
} Polynomial;
//variables accessible in utils file
static Polynomial *polynomialArray;
int num_polynomial; // counter to keep track of the number of polynomials
I think the problem is here free(polynomialArray[index].polynomialTerm); if index > num_polynomial, then the value here polynomialArray[index].polynomialTerm is garbage. you don't need to free it. instead you should write it something like that:
void insert(Polynomial* element, int index) {
if(index >= num_polynomial) { /* probably should be >= depends on your implementation */
polynomialArray = (Polynomial*)realloc(polynomialArray, (index + 1) * sizeof(Polynomial));
}
else
{
free(polynomialArray[index].polynomialTerm);
}
polynomialArray[index] = *element;
}
also, this is a bit risky. for a two main reasons:
you don't increment num_polynomial if index is bigger.
you don't know how bigger index is, so you might allocate a much bigger memory, and later, if you try to reach anything between the previous num_polynomial and the new size, you get to unknown area, and probably get segfault again.
I think the issue is that subtract is returning a pointer into your dynamically allocated array, but then insert realloc's that array, leaving the pointer returned by subtract (passed into insert as element) dangling.
So at the line you have marked Problem here?, element is pointing at the just implicitly freed (by realloc) array, which may well have been overwritten by the memory management system. In any case, accessing memory after its freed gives undefined behavior.

Resources