Reputation: 33
I am still very new to C, and am trying to figure out why I (believe) that I am getting a segmentation fault. I say believe, because the exe stops working, and so I just try and run it in Eclipse's debugger, and that's where I see the error happening. Any help/suggestions/criticisms are highly welcomed.
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
struct node *left;
struct node *right;
double key;
} node;
void addNode(double value, node **node);
double dRand();
//node* search(double value, node *root);
void killTree(node *root);
int main(void)
{
int nodesToAdd, i;
node *n = NULL;
node **p = &n;
nodesToAdd = 10;
for(i=0;i<nodesToAdd;i++)
{
printf("DEBUG: Adding node %d to tree\n", i+1);
addNode(dRand(), p);
}
printf("DEBUG: Finished creating tree\n");
printf("DEBUG: Freeing memory of tree\n");
killTree(n);
return 0;
}
double dRand()
{
return ((double)rand()/RAND_MAX)*10;
}
void addNode(double value, node **tree)
{
node *insert = malloc(sizeof(*insert));
insert->key = value;
while(*tree){
if(value < (*tree)->key) tree = &(*tree)->left;
else if(value > (*tree)->key) tree = &(*tree)->right;
else return;
}
*tree = insert;
}
void killTree(node *node)
{
if(!node){}
else
{
killTree(node->left);
killTree(node->right);
printf("DEBUG: Deleting pointer to node of value %f from mem\n", node->key);
free(node);
}
}
EDIT: I think that the error comes from trying to reference the right and left nodes before they are allocated memory, but I'm not sure what it is that I am doing wrong.
EDIT2:Thanks so much, that worked wonderfully!
Upvotes: 3
Views: 402
Reputation: 66254
You have a memory leak in your addNode function if a match is found. You allocate, then search. You should search, then allocate only if the search failed.
Regarding your crash, you're not initializing a new node's left and right pointers to NULL. This is critical. The next time you enter the tree to chase down a search, you will dereference indeterminate pointers, and invoke undefined behavior as a result.
Perhaps something like this:
void addNode(double value, node **tree)
{
// search first
while (*tree)
{
if (value < (*tree)->key)
tree = &(*tree)->left;
else if((*tree)->key < value)
tree = &(*tree)->right;
else return;
}
// no match, so add
*tree = malloc(sizeof(**tree));
(*tree)->key = value;
(*tree)->left = (*tree)->right = NULL; // note: set to null
}
Next, though not critical, your main()
function has no need for p
. You can use your node pointer by-address directly:
int main(void)
{
int nodesToAdd, i;
node *n = NULL;
nodesToAdd = 10;
for(i=0;i<nodesToAdd;i++)
{
printf("DEBUG: Adding node %d to tree\n", i+1);
addNode(dRand(), &n);
}
printf("DEBUG: Finished creating tree\n");
printf("DEBUG: Freeing memory of tree\n");
killTree(n);
return 0;
}
And for what it's worth, if your new to C, this isn't terrible. Grasping double-indirection is a common stall-point in the C learning curve, and your use in your add function wasn't terrible at all. Keep at it.
Upvotes: 3