I've tried applying advice from other threads regarding the EXC_BAD_ACCESS message, but with no success. The note appears next to Node Create_Child (Node Parent_Node, int item) {.
typedef struct {
int Win_Loss;
int parent;
int identifier;
int Object_Moved;
int Wolf;
int Goat;
int Salad;
int Boat;
} Node;
Node Create_Child (Node Parent_Node, int item) {
Node Child;
Child.Boat = (-1)*Parent_Node.Boat;
Child.Wolf = Parent_Node.Wolf;
Child.Goat = Parent_Node.Wolf;
Child.Salad = Parent_Node.Salad;
int* Child_Items[] = {&Child.Wolf, &Child.Goat, &Child.Salad, &Child.Boat};
Child.parent = Parent_Node.identifier;
Child_Items[item][0] *= (-1);
Child.Object_Moved = item;
return Child;
}
Any insight? Memory allocation doesn't seem to be the issue, but I'm probably not seeing something.
The pointers e.g. Child.Wolf are local to the function, they have no meaning outside your Create_Child function yet you assign those addresses to Child.Object_Moved and return a copy of it.
You should allocate Child on the heap instead
Node* Create_Child(Node Parent_Node, int item) {
Node* Child = malloc(sizeof(Node));
Child->Boat = -1*Parent_Node.Boat;
...
int* Child_Items[] = { &Child->Wolf, .. };
Also it is good to sanity check all arguments to your function
before using them. e.g. item in range?, Parent_Node valid info?
Related
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 10
// A hashtable is a mixture of a linked list and array
typedef struct node NODE;
struct node{
int value;
NODE* next;
};
int hash(int);
void insert(int,NODE **);
int main(){
NODE* hashtable[SIZE];
insert(12,&hashtable[SIZE]);
printf("%d\n",hashtable[5]->value);
}
int hash(int data){
return data%7;
}
void insert(int value,NODE **table){
int loc = hash(value);
NODE* temp = malloc(sizeof(NODE));
temp->next = NULL;
temp->value = value;
*table[loc] = *temp;
printf("%d\n",table[loc]->value);
}
The above code prints :
12 and
27475674 (A random number probably the location.)
how do I get it to print 12 and 12 i.e. how to make a change in the array. I want to fill array[5] with the location of a node created to store a value.
The expression *table[loc] is equal to *(table[loc]) which might not be what you want, since then you will dereference an uninitialized pointer.
Then the assignment copies the contents of *temp into some seemingly random memory.
You then discard the memory you just allocated leading to a memory leak.
There's also no attempt to make a linked list of the hash-bucket.
Try instead to initially create the hashtable array in the main function with initialization to make all pointers to NULL:
NODE* hashtable[SIZE] = { NULL }; // Will initialize all elements to NULL
Then when inserting the node, actually link it into the bucket-list:
temp->next = table[loc];
table[loc] = temp;
This is just a simple change which I have made to your program which will tell you what you are actually doing wrong.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 10
// A hashtable is a mixture of a linked list and array
typedef struct node NODE;
struct node {
int value;
NODE* next;
};
NODE *hashtable[SIZE] = { NULL };
int hash(int);
int insert(int); //, NODE **);
int main(void)
{
int loc = insert(12); //, &hashtable[SIZE]);
if (loc < SIZE) {
if (hashtable[loc]) {
printf("%d\n", hashtable[loc]->value);
} else {
printf("err: invalid pointer received\n");
}
}
return 0;
}
int hash(int data)
{
return data%7;
}
int insert(int value) //, NODE *table[])
{
int loc = hash(value);
printf("loc = %d\n", loc);
if (loc < SIZE) {
NODE *temp = (NODE *) malloc(sizeof(NODE));
temp->value = value;
temp->next = NULL;
hashtable[loc] = temp;
printf("%d\n", hashtable[loc]->value);
}
return loc;
}
Here I have declared the hashtable globally just to make sure that, the value which you are trying to update is visible to both the functions. And that's the problem in your code. Whatever new address you are allocating for temp is having address 'x', however you are trying to access invalid address from your main function. I just wanted to give you hint. Hope this helps you. Enjoy!
I'm pretty new to C world and I don't know how is the correct way to delete this data structure avoiding memory leaks and segmentation faults.
The data structure is this:
typedef struct Node {
int id;
struct Node *parent; /* node's parent */
struct Node *suffix_node;
int first_char_index;
int last_char_index;
bool is_leaf;
struct Node **children; /* node's children */
int children_size; /* size of children structure */
int children_count; /* # of children */
int depth;
}Node;
typedef struct SuffixTree {
Node *root;
int nodes_count;
char *string;
}SuffixTree;
What I would do is, from a pointer to SuffixTree structure, freeing entirely tree.
I have tried to do this:
void deleteSubTree(Node *nd)
{
if (nd->is_leaf)
{
free(nd->children);
free(nd);
return;
}
int i = 0;
for(;i < nd->children_count; ++i)
{
deleteSubTree(nd->children[i]);
}
free(nd->children);
free(nd);
return;
}
void deleteSuffixTree(SuffixTree *st)
{
deleteSubTree(st->root);
free(st);
}
But it is not correct.
EDIT:
This is main:
int main()
{ char *str = "BOOK\0";
SuffixTree *st = createSuffixTree(str);
deleteSuffixTree(st);
return 0;
}
And this is how I allocate tree and nodes:
Node* createNode(){
Node *stn = (Node*)malloc(sizeof(Node));
stn->id = node_id++;
stn->parent = (Node*)malloc(sizeof(Node));
stn->suffix_node = (Node*)malloc(sizeof(Node));
stn->first_char_index = -1;
stn->last_char_index = -1;
stn->children_size = NODE_BASE_DEGREE;
stn->children_count = 0;
stn->children = (Node**)malloc(stn->children_size*sizeof(Node*));
stn->is_leaf = true;
stn->depth = 1;
return stn;
}
SuffixTree* createSuffixTree(char *str)
{
SuffixTree *st = (SuffixTree*)malloc(sizeof(SuffixTree));
st->root = createNode();
st->root->parent = (Node*)malloc(sizeof(Node));
st->root->parent->id = -1;
st->nodes_count = 1;
st->string = str;
makeTreeWithUkkonen(st);
return st;
}
makeTreeWithUkkonen is correct, I can display correct tree after createSuffixTree() call.
As GeoMad89 said, you malloc already existing nodes in the createNode() method.
If you change your createNode() code into this:
Node* createNode(Node* parent, Node* suffixNode){
Node *stn = (Node*)malloc(sizeof(Node));
stn->id = node_id++;
stn->parent = parent; //(Node*)malloc(sizeof(Node));
if(suffixNode != NULL)
stn->suffix_node = suffixNode; //(Node*)malloc(sizeof(Node));
stn->first_char_index = -1;
stn->last_char_index = -1;
stn->children_size = NODE_BASE_DEGREE;
stn->children_count = 0;
stn->children = (Node**)malloc(stn->children_size*sizeof(Node*));
if(parent != NULL){
parent->children[parent->children_count++] = stn;
parent->is_leaf = false;
}
stn->is_leaf = true;
stn->depth = 1;
return stn;
}
And if you try it with valgrind, using this toy main:
main(int argc, char** argv){
Node* root = createNode(NULL, NULL);
Node* node1 = createNode(root, NULL);
Node* node2 = createNode(root, NULL);
Node* node3 = createNode(node1, NULL);
deleteSubTree(root);
return 0;
}
You will see that all the malloc'd memory will be freed!
Needless to say, this code works only with NODE_BASE_DEGREE=2, otherwise, if you use a greater NODE_BASE_DEGREE value, you have to realloc the children array.
I have noticed that the leaf nodes have their children array not empty, because children_size is equal to NODE_BASE_DEGREE.
Try to delete the elements of the array in the leaves before eliminating them.
I have noticed two possible memory leaks:
In createNode, i suppose that the parent of the node that you going to create already exist, there is no need to malloc a space for it. But anyway you change the value of the pointer of parent in createSuffixTree, at least in the root of the tree, so this memory that you have allocated in createNode for parent is lost.
I don't know what suffix_node is, if is a node of the tree there is the same problem of the point one. But if is another node and so it is correct allocate memory, you don't freed when deleted the tree.
I'm writing a simple linked list implementation for the sake of learning. My linked list consists of node structures that contain an int value and a pointer to the next node. When I run my code, it loops endlessly even though it should terminate when it reaches a NULL pointer. What am I doing wrong?
#include <stdio.h>
struct node {
int value;
struct node *next_node;
};
struct node * add_node(struct node *parent, int value)
{
struct node child;
child.value = value;
child.next_node = NULL;
parent->next_node = &child;
return parent->next_node;
}
void print_all(struct node *root)
{
struct node *current = root;
while (current != NULL) {
printf("%d\n", current->value);
sleep(1);
current = current->next_node;
}
}
int main()
{
struct node root;
root.value = 3;
struct node *one;
one = add_node(&root, 5);
print_all(&root);
}
Your program exhibits undefined behavior: you are setting a pointer to a locally allocated struct here:
struct node child;
child.value = value;
child.next_node = NULL;
parent->next_node = &child;
return parent->next_node;
Since child is on the stack, returning a parent pointing to it leads to undefined behavior.
You need to allocate child dynamically to make it work:
struct node *pchild = malloc(sizeof(struct node));
// In production code you check malloc result here...
pchild->value = value;
pchild->next_node = NULL;
parent->next_node = pchild;
return parent->next_node;
Now that you have dynamically allocated memory, do not forget to call free on each of the dynamically allocated nodes of your linked list to prevent memory leaks.
add_node returns a pointer to a local variable which immediately goes out of scope and may be reused by other functions. Attempting to access this in print_all results in undefined behaviour. In your case, it appears the address is reused by the current pointer, leaving root->next_node pointing to root.
To fix this, you should allocate memory for the new node in add_node
struct node * add_node(struct node *parent, int value)
{
struct node* child = malloc(sizeof(*child));
if (child == NULL) {
return NULL;
}
child->value = value;
child->next_node = NULL;
parent->next_node = child;
return child;
}
Since this allocates memory dynamically, you'll need to call free later. Remember not to try to free root unless you change it to be allocated using malloc too.
Disclaimer: This is for an assignment. I am not asking for explicit code answers, only help understanding why my code isn't working.
I am trying to implement a basic Binary Search Tree, but I am having problems with my _addNode(...) function.
Here's the problem. When I walk through my code with the debugger, I notice that leaf nodes are created infinitely on both sides (left and right) so aside from the creation of the root, there is never any point when a leaf node is NULL. The problem is that I am asking my program to create a new node whenever it finds a NULL value where a leaf would be. Therefore, if there are never any NULL values, there will never be any new leaves created, right?
The other issue I'm running into is with my compare(...) function. Stepping through it in the debugger shows it to iterate through the function several times, never actually returning a value. When it returns to the calling function, it drops back into the compare(...) function and loops infinitely. Again, I don't know why this is happening considering I have valid return statements in each if statement.
Here is all the code you'll probably need. If I left something out, let me know and I'll post it.
struct Node {
TYPE val;
struct Node *left;
struct Node *right;
};
struct BSTree {
struct Node *root;
int cnt;
};
struct data {
int number;
char *name;
};
int compare(TYPE left, TYPE right)
{
assert(left != 0);
assert(right != 0);
struct data *leftData = (struct data *) left;
struct data *rightData = (struct data *) right;
if (leftData->number < rightData->number) {
return -1;
}
if (leftData->number > rightData->number) {
return 1;
} else return 0;
}
void addBSTree(struct BSTree *tree, TYPE val)
{
tree->root = _addNode(tree->root, val);
tree->cnt++;
}
struct Node *_addNode(struct Node *cur, TYPE val)
{
assert(val != 0);
if(cur == NULL) {
struct Node * newNode = malloc(sizeof(struct Node));
newNode->val = val;
return newNode;
}
if (compare(val, cur->val) == -1) {
//(val < cur->val)
cur->left = _addNode(cur->left, val);
} else cur->right = _addNode(cur->right, val);
return cur;
}
Edit: Adding the below function(s)
int main(int argc, char *argv[])
{
struct BSTree *tree = newBSTree();
/*Create value of the type of data that you want to store*/
struct data myData1;
struct data myData2;
struct data myData3;
struct data myData4;
myData1.number = 5;
myData1.name = "rooty";
myData2.number = 1;
myData2.name = "lefty";
myData3.number = 10;
myData3.name = "righty";
myData4.number = 3;
myData4.name = "righty";
/*add the values to BST*/
addBSTree(tree, &myData1);
addBSTree(tree, &myData2);
addBSTree(tree, &myData3);
addBSTree(tree, &myData4);
/*Print the entire tree*/
printTree(tree);
/*(( 1 ( 3 ) ) 5 ( 10 ))*/
return 1;
}
Maybe you could try setting right and left to NULL right after malloc:
struct Node * newNode = malloc(sizeof(struct Node));
newNode->left = NULL;
newNode->right = NULL;
Check this line here (or the corresponding for left):
cur->right = _addNode(cur->right, val);
If cur->right == 0, it's fine. But if cur->right != 0, the node that was sitting there will be replaced by the return value of _addNode, which ultimately is not a whole branch, but just one node.
I like to explicitly 0-out values in a struct after a malloc using memset(newNode, 0, sizeof(struct Node)). Others might disagree.
I have an obvious question, yet I'm perplexed by the problem.
Ok, first let me overview the situation. I have a structure called ENTITY that is used to hold the attributes for entities in a game. I recently added more members to the structure. The program runs perfect, but when I quit, windows pops up an error screen saying "XXX.exe has stopped working...check online for solution...blah blah".
So, to troubleshoot, I removed a few members from the ENTITY structure and the program runs fine and exits fine. ????
(compiled with Dev-cpp)
The code:
typedef struct _ENTITY
{
char classname[16];
int health;
int vel_x;
int vel_y;
int direction;
int frame;
int flag;
SDL_Rect bbox;
struct _ENTITY *next;
struct _ENTITY *owner;
struct _ENTITY *goal;
void (*think) ();
float nextthink;
} ENTITY;
The function that allocates memory to ENTITY structures
ENTITY *ENTITY_spawn (void)
{
ENTITY *node, *old_node;
int i;
node = ENTITY_head; // Top of list
// Find end of list
for (i = 0; node; i++)
{
old_node = node;
node = node->next;
}
// Allocate
node = (ENTITY*)calloc (1, sizeof (ENTITY));
if (i)
old_node->next = node;
else
ENTITY_head = node;
return node;
}
(EDIT 4/8/12)
-Used calloc instead of malloc
-Inserted void in function parameters
-Got rid of NULL_void
-Could not get rid of (ENTITY*) cast, the compiler complains that it could not convert type void (because I didn't include stdlib.h?)
Here's how I remove ENTITY(s) when exiting the program:
void ENTITY_cleanup (void)
{
ENTITY *node, *old_node;
node = ENTITY_head;
while (node)
{
old_node = node->next;
free (node);
node = old_node;
}
}