I'm writing a code that should read data from a file and then add them to a linked list , following is the code to read from the file:
void readFromFile(List l)
{
system("cls");
FILE *eqFile;
string readFile,line;
printf("\n\t\t\tEnter the title of the file to read equations from\n\t\t\t");
scanf("\t\t\t%s",readFile);
eqFile=fopen(readFile,"r");
/*To make sure that the file does exist*/
while (eqFile == NULL)
{
printf("\n\t\t\tERROR!! The file you requested doesn't exist. Enter the title correctly please\n\t\t\t");
scanf("\t\t\t%s",readFile);
eqFile=fopen(readFile,"r");
}
while (fscanf(eqFile,"%s",line) != EOF)
{
addNode(l,line);//create a new node and fill it with the data
count++; //Counter to count the number of nodes in the list
}
fclose(eqFile);
system("cls");
printf("\n\t\t\tDATA READ SUCCESSFULLY!\n\t\tPress any key to return to the menu.\t\t\t");
getch();
menu();
}
But it gives runtime error when I worked in the debug mode I found out that the problem is in the "addNode" function, following is the function :
/*Function that adds a node to the list*/
void addNode(List l, string s)
{
position temp,temp2;
temp2=l;
temp = (position)malloc(sizeof(struct node));
if(temp == NULL)
printf("\n\t\t\tSORRY! MEMORY OUT OF SPACE!!\n");
else
{
strcpy(temp->eq,s);
while(temp2->next != NULL)
{
temp2=temp2->next;
}
(temp2)-> next= temp;
}
}
The error happens at this statement :
while(temp2->next != NULL)
{
temp2=temp2->next;
}
I looked for the reason of the error and I found that it occurs when I try to access something that can't be accessed by memory. But I have used this statement several times before in different codes and it didn't cause any problem. Could any one help me please telling me what's wrong with my code? Or how can I avoid this error?
For linked list, addition of new node must have it's next as null, if you are adding the node at the end.
I personally do not like this syntax.
while(temp2->next != NULL)
{
temp2=temp2->next;
}
The following seems a lot safer to me.
for (position p = temp2; p != NULL; p = p->next)
{
}
The second version would've prevented the segmentation fault in your code.
Related
I cannot get this function to work properly. It crashes when I try to delete a specific record. What do I need to change for it to work as expected?
//Delete Students Function
void delete_single_Student(Student *pfirst, int id)
{
int search_id;
bool found = false;
Student *pcurrent = pfirst;
Student *temp = NULL;
printf("Please enter the student ID of the student that will be deleted.\n");
scanf("%d", &search_id);
while (search_id < 999 || search_id > 9999)
{
printf("\nPlease enter a valid id.\n");
scanf("%d", &search_id);
}
do
{
temp = pcurrent;
pcurrent = pcurrent->next;
if (pfirst->id == search_id)
{
found == true;
printf("**********************\n\n");
printf(" Student %d Deleted \n\n", search_id);
printf("*********************\n\n");
pfirst = pfirst->next;
free(temp);
break;
}
} while (found != true);
}
Notice that you are querying pfirst, but you are not generally changing pfirst in your loop. The conditional will only be true if the first element is your result. Additionally, found != true is always true, so you are bound to end up with a pcurrent null pointer after traveling the list and upon referencing pcurrrent->next, you bomb.
I would suggest that you incrementally attack with easier problems.
1) Just write a procedure to print each element, terminating when the pointer is null. You do not need a found variable.
2) Repeat number #1 but print that element side by side with its predecessor, requiring you to track the previous element.
3) After mastering #2, you will see that the first element is a special case and that you cannot really solve the problem without having access to the information that the calling function had.
I'm currently stuck at this part in coding a dictionary projects. I can pretty much breeze through everything else, but here.
My problem is that whenever I return the dictionary(a linked list head) to the main function after it passes through this particular if statement, an exception pops out.
item *deleteEntry(item *entry, item *dictionary)
{
item *cont,*temp;
int check;
check = 0;
for (cont = dictionary; cont != NULL; cont = cont->next)
{
if (!strcmp(cont->word, entry->word) && cont == dictionary)
{
dictionary = cont->next;
free(cont);
check = 1;
break;
}
//other non-problematic entry-deletion statements
}
if (!check)
return 0;
return dictionary;
}
Even though it does store the data correctly inside the function(I've tested by printing), it just doesn't work when returned to the main function.
Here's the part where I call the function
printf("\nEnter word to delete entry: ");
getchar();
fgets(entry->word, WORDLIMIT, stdin);
if (dictionary[toupper(entry->word[0]) - 65] == NULL)
printf("\nWord Does not exist");
else
{
cont = deleteEntry(entry, dictionary[toupper(entry->word[0]) - 65]);
if (cont)
dictionary[toupper(entry->word[0] - 65)] = cont;
else
printf("\nError: Word doesn't exist in archive %d!!\n", toupper(entry->word[0]));
And the exception is :
Access violation reading location 0xDDDDDDDD. (I don't know what this is, even after google searches. please enlighten me)
And this is my first post here, so I'll take my chance to say Thank you for this is the first place I go to whenever I get stuck :)
Problem Solved!
As I commented, I think the key point is dictionary[toupper(entry->word[0] - 65)]
This code causes to access your array of pointers out of bounds.
E.g.
entry->word[0] = 'a'
toupper(entry->word[0] - 65) = 32
But I think that your array has 26 elements.
It must be
dictionary[toupper(entry->word[0]) - 65]
/* this is part of your code. check comments added by me
*/
for (cont = dictionary; cont != NULL; cont = cont->next /*->next can be null*/)
{
if (!strcmp(cont->word, entry->word) && cont == dictionary)
{
dictionary = cont->next; /*if ->next above is null than boom (null->null)*/
free(cont);
check = 1;
break;
}
//other non-problematic entry-deletion statements
}
/* better use this */
cont = dictionary->next;
while(cont){
if(...){
dictionary=cont->next;
free(cont);
break; /* or return something*/
}
cont=cont->Next;
}
/*return other thing*/
I am trying to calculate the frequency of each node as I add them to the tree, instead of inserting a new element. For some reason when a comparing a new key to every element in the current tree, the if statement will not return 1 if they are both identical. BUT, the function will still add 1 to the frequency of the existing node. This is very puzzling to me, as I don't know why it would skip over the return 1, and continue searching through the tree. Thank you for help/advice in advance.
struct:
typedef struct node {
char* key;
struct node *left;
struct node *right;
int height;
int frequency;
}node;
This is my parsing function:
while(fgets(str, 100, textFile)) {
token = strtok(str," \n");
while (token != NULL)
{
key = strdup(token);
if((sameFrequency(root, key)==1)&&root!=NULL) {
printf("%s", key);
free(key);
token = strtok (NULL, " \n");
}
else {
root = insert(root, key);
//printf("%s\n", key);
free(key);
token = strtok (NULL, " \n");
}
}
if(ferror(textFile))
{
printf("you done messed up a-a-ron");
return(0);
}
}
Function to check the frequency of each node:
int sameFrequency(node *node, char* key) {
if (node != NULL) {
if(strcmp(key, node->key)==0){ //This statement is true in some cases, but will not return the 1
node->frequency = node->frequency+1;
printf("%d\n",node->frequency);
return 1;
}
sameFrequency(node->left, key);
sameFrequency(node->right, key);
}
else return 0;
}
Input would look something like this:
wrn69 flr830 flr662 flr830 flr830
flr231
The output (after printing in preOrder):
key: wrn69, frequency: 1
key: flr830, frequency: 3
key: flr662, frequency: 1
key: flr231, frequency: 1
key: flr830, frequency: 1
key: flr830, frequency: 1
I want this to print everything shown, but I don't want the same key to be inserted into the tree, just incremement its frequency by 1.
TL;DR: Function skipping over return value, but still running code in the if statement, have no idea whats wrong, even after debugging.
I'm not sure what your code is trying to do, since you do not define your node struct, however your function int sameFrequency(node *node, char* key) has an obvious bug: not all code paths return a value. Reformatting a bit for clarity, you can see that if strcmp(key, key)!=0 then the return is undefined:
int sameFrequency(node *node, char* key) {
if (node != NULL) {
if(strcmp(key, node->key)==0){
node->frequency = node->frequency+1;
printf("%d\n",node->frequency);
return 1;
}
else {
sameFrequency(node->left, key);
sameFrequency(node->right, key);
// Continue on out of the "if" statements without returning anything.
}
}
else {
return 0;
}
// NO RETURN STATEMENT HERE
}
My compiler generates a warning for this:
warning C4715: 'sameFrequency' : not all control paths return a value
Surely yours must be doing so as well, unless you intentionally disabled them. Such warnings are important, and should always be cleared up before finishing your code.
I'm guessing you want to do something like this, perhaps?
int sameFrequency(node *node, char* key) {
if (node != NULL) {
if(strcmp(key, node->key)==0){
node->frequency = node->frequency+1;
printf("%d\n",node->frequency);
return 1;
}
else {
int found;
if ((found = sameFrequency(node->left, key)) != 0)
return found;
if ((found = sameFrequency(node->right, key)) != 0)
return found;
return 0;
}
}
else {
return 0;
}
}
This clears the compiler warning.
Incidentally, the following if statement is probably in the wrong order:
if((sameFrequency(root, key)==1)&&root!=NULL) {
Since && statements in C execute left to right the following makes more sense:
if(root!=NULL && (sameFrequency(root, key)==1)) {
i have a pointer problem:
SearchResults* pointy;
pointy = returnResults();
if(pointy != NULL && pointy->results[0] != NULL)
{
HandleResponse();
printf("sharp");
}else{
//do other things
}
if(pointy == NULL){
printf("blunt");
}
if(pointy->results[0] == NULL){
printf("wah!!!");
}
in the debugger the code correctly works and i get "sharp" but under the same conditions in the bash terminal i get "wah!!!"
typedef struct SearchResults
{
TreeNode* results[40];
int searchIndex;
} SearchResults;
SearchResults* lostAndFound;
SearchResults* returnResults()
{
return lostAndFound;
}
Found a Problem in both the debug and release variations there is a .csv file.. the debug reads and writes to it perfectly fine whereas the release seems to steamroll it into nothigness.
So i am trying to prevent the segfault that is occuring in the following code. It is occuring because i am trying to access the next element in the list that does not exist yet. How do i prevent this?
while (vm->item_list.head->data !=NULL) {
printf("%-10s",vm->item_list.head->data->id);
printf("%-20s",vm->item_list.head->data->name);
printf("%-70s",vm->item_list.head->data->description);
printf("%-15d",vm->item_list.head->data->on_hand);
printf("%s","$");
printf("%d",vm->item_list.head->data->price.dollars);
printf("%s",".");
printf("%02d",vm->item_list.head->data->price.cents);
printf("\n");
vm->item_list.head = vm->item_list.head->next;
}
printf("\n");
}
use something like while ((vm->item_list.head != NULL ) && (vm->item_list.head->data !=NULL))
In the initialization phase of the list, you have to declare the end of the list, in this case your next pointer, with NULL. If you do this, than you ensure that this pointer doesn't point in a undefined region.
So than you can check like this:
while (vm->item_list.head->data !=NULL) {
printf("%-10s",vm->item_list.head->data->id);
printf("%-20s",vm->item_list.head->data->name);
printf("%-70s",vm->item_list.head->data->description);
printf("%-15d",vm->item_list.head->data->on_hand);
printf("%s","$");
printf("%d",vm->item_list.head->data->price.dollars);
printf("%s",".");
printf("%02d",vm->item_list.head->data->price.cents);
printf("\n");
if(vm->item_list.head->next != NULL){
vm->item_list.head = vm->item_list.head->next;
}else{
break;
}
}
Or you can do it like this:
ItemNode* node = vm->item_list.head;
while (node->data !=NULL || node->next != NULL) {
printf("%-10s",node->data->id);
printf("%-20s",node->data->name);
printf("%-70s",node->data->description);
printf("%-15d",node->data->on_hand);
printf("%s","$");
printf("%d",node->data->price.dollars);
printf("%s",".");
printf("%02d",node->data->price.cents);
printf("\n");
node = node->next;
}