EXC_BAD ACCESS in memcpy - c

I trying to build a BST and insert nodes in it. However while creating a new node I keep getting exc_bad access error.What can be the reason? Here is my code:
struct Node *node_create(struct BSTree *bst,void *nodeKey, struct Value *nodeVal, struct Node *rightChild, struct Node *leftChild)
{
struct Node *node = malloc(sizeof *node);
nodeKey= malloc (sizeof (bst->key_size));
nodeVal = malloc(sizeof(bst->value_size));
size_t sizeKey = sizeof(nodeKey);
memcpy(node->key, nodeKey, sizeKey); // exc_bad access
size_t sizeVal = sizeof (nodeVal);
memcpy(node->val, nodeVal, sizeVal); // exc_bad access
node->right = rightChild;
node->left = leftChild;
return node;
}
struct Node {
void *key;
struct Value *val;
struct Node *left;
struct Node *right;
};
struct BSTree {
size_t key_size, key_alignment;
size_t value_size, value_alignment;
int (*compare_func)(void *, void *);
struct Node *root;
// ... Maybe some other stuff.
};
struct Value {
char name[10];
int id;
};

Without knowing what Node, looks like, I'd say, even though you've allocated for node, you've not allocated all the members (which appear to be pointers).
Change your code to something like:
// Allocate node
struct Node *node = malloc(sizeof *node);
// Now members
node->key = malloc (sizeof (bst->key_size));
// :
If you are passing in the key and value, then do a memcpy of those values to the above locations. But hard to say without further code...

Without looking at the Node structure, I would guess what you want to do is:
if node is defined as
struct Node {
void *key;
struct Value *val;
struct Node *right;
struct Node *left;
};
then
struct Node *node_create(struct BSTree *bst,void *nodeKey, struct Value *nodeVal, struct Node *rightChild, struct Node *leftChild)
{
struct Node *node = malloc(sizeof *node);
node->key = malloc(bst->key_size); /* No sizeof here */
node->val = malloc(bst->value_size);
memcpy(node->key, nodeKey, bst->key_size);
memcpy(node->val, nodeVal, bst->value_size);
node->right = rightChild;
node->left = leftChild;
return node;
}
As you don't check for the returns of the mallocs (which is a design choice that can e justified), you can even write it simpler that way.
struct Node *node_create(struct BSTree *bst,void *nodeKey, struct Value *nodeVal, struct Node *rightChild, struct Node *leftChild)
{
struct Node *node = malloc(sizeof *node);
node->key = memcpy(malloc(bst->key_size) , nodeKey, bst->key_size);
node->val = memcpy(malloc(bst->value_size), nodeVal, bst->value_size);
node->right = rightChild;
node->left = leftChild;
return node;
}
There are people that cringe at this style but I prefer to not dilute my code too much on redundancies.

Related

What exactly the meaning of structure pointer

struct Node
{
int data;
struct Node* left, *right;
};
What exactly the meaning of this struct Node *? Is the function below returning a pointer to a Node?
struct Node* newNode(int data)
{
struct Node* node = new(struct Node);
node->data = data;
node->left = node->right = NULL;
return (node);
}
struct Node;
Is the name of your struct.
What exactly the meaning of this struct Node*?
struct Node* node;
You're declaring a pointer to the struct Node that needs to be allocated with some memory. There is no new keyword in C. You need to use malloc() to allocate the required bytes of memory. You can allocate that like this:
struct Node* node = (struct Node *)malloc(sizeof(struct Node));
Is it returning a pointer to a Node?
This line:
return (node);
Returns the type of struct Node* to the function.

Assign a pointer to a struct that is a member of a struct of the same type to another pointer to a struct of the same type

This question sounds super confusing even for me, and it may seem obvious or already answered, but I have searched a lot and although I found interesting things, I didn't find an answer exactly for my question. Here is some C code that will show much better my doubt:
typedef struct Node_struct {
char keyLine[100];
int occurrences;
struct Node* leftChild;
struct Node* rightChild;
struct Node* parent;
} Node;
typedef struct Tree_struct {
Node* root;
} Tree;
int insertNode(Tree* myTree, Node* newNode) {
...
Node* currentNode = myTree->root;
...
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = (Node*)currentNode->leftChild;
}
...
}
Is this code correct? Since currentNode is of type Node*, and currentNode->leftChild is of type struct Node*, I had to cast (Node*)currentNode->leftChild so that it could be assigned to currentNode. But I am not sure if this is correct, necessary, or if there is a better way to do the same.
Similarly, I also have this:
Node* coverNode = NULL;
...
coverNode->leftChild = (struct Node*)newNode;
What should be written
Suppose the code in the question were written like this:
typedef struct Node { // Not Node_struct as in the question!
char keyLine[100];
int occurrences;
struct Node* leftChild;
struct Node* rightChild;
struct Node* parent;
} Node;
Then the name Node would be a synonym (alias) for struct Node. (For any typedef X Y;, Y becomes a synonym for type X — where in your case, X would be struct Node and Y would be Node.)
The cast in:
currentNode = (Node *)currentNode->leftChild;
would be unnecessary (but mostly harmless) because it would be a no-op — the types struct Node * and Node * would be two names for the same pointer type. Similarly for:
coverNode->leftChild = (struct Node *)newNode;
The cast would be unnecessary but (mostly) harmless. There would be a small risk of confusing people with the cast. It is better to avoid casts when possible, and these would be better written without the casts:
currentNode = currentNode->leftChild;
coverNode->leftChild = newNode;
What is written
typedef struct Node_struct {
char keyLine[100];
int occurrences;
struct Node* leftChild;
struct Node* rightChild;
struct Node* parent;
} Node;
Now we have three type names in play: struct Node_struct, struct Node, and Node. In this case, struct Node_struct and Node are synonyms, and struct Node is an incomplete structure type (or, at least, it is not completed by any code in the question). It is wholly unrelated to either struct Node_struct or Node except by the coincidence that it is referenced inside the structure.
With this notation, the casts are 'necessary' because you're converting between pointers to unrelated types (struct Node * and struct Node_struct *). Fortunately, there are rules that say all structure type pointers are inter-convertible and must have the same size and alignment requirements (C11 §6.2.5 Types ¶28 and §6.3.2.3 Pointers ¶7).
But you should drop the _struct part of Node_struct to make the rules of the first part of this answer apply. In C, it is (IMO) sensible to use:
typedef struct SomeTag SomeTag;
so that you can subsequently use SomeTag * etc. The first SomeTag is in the tags name space and does not conflict with the second SomeTag, which is in the ordinary identifiers name space. See C11 §6.2.3 Name spaces of identifiers.
See also:
Which part of the C standard allows this code to compile?
Does the C standard consider that there are one or two struct uperms_entry types in this code?
C style/C++ correctness — is struct, union, enum tag same as type name bad in any way?
In c++, when you say struct Node, Node [immediately] becomes a type. So, you could say:
struct Node {
char keyLine[100];
int occurrences;
Node *leftChild;
Node *rightChild;
Node *parent;
};
struct Tree {
Node *root;
};
int
insertNode(Tree *myTree, Node *newNode)
{
Node *currentNode = myTree->root;
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = currentNode->leftChild;
}
}
But, in c, it is merely in the "tag" namespace and does not define a type. Thus, you want:
typedef struct Node {
char keyLine[100];
int occurrences;
struct Node *leftChild;
struct Node *rightChild;
struct Node *parent;
} Node;
typedef struct Tree_struct {
Node *root;
} Tree;
int
insertNode(Tree *myTree, Node *newNode)
{
Node *currentNode = myTree->root;
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = currentNode->leftChild;
}
}
As an alternative, you can use a forward declaration:
// forward declaration
struct Node;
typedef struct Node Node;
struct Node {
char keyLine[100];
int occurrences;
Node *leftChild;
Node *rightChild;
Node *parent;
};
typedef struct Tree_struct {
Node *root;
} Tree;
int
insertNode(Tree *myTree, Node *newNode)
{
Node *currentNode = myTree->root;
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = currentNode->leftChild;
}
}
Note that the struct name does not have to match the type name:
// forward declaration
struct Node_struct;
typedef struct Node_struct Node;
struct Node_struct {
char keyLine[100];
int occurrences;
Node *leftChild;
Node *rightChild;
Node *parent;
};
typedef struct Tree_struct {
Node *root;
} Tree;
int
insertNode(Tree *myTree, Node *newNode)
{
Node *currentNode = myTree->root;
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = currentNode->leftChild;
}
}
To allow cross linking of your two structs, we could do:
// forward declaration
struct Node_struct;
typedef struct Node_struct Node;
struct Tree_struct;
typedef struct Tree_struct Tree;
struct Node_struct {
char keyLine[100];
int occurrences;
Node *leftChild;
Node *rightChild;
Node *parent;
Tree *tree;
};
struct Tree_struct {
Node *root;
};
int
insertNode(Tree *myTree, Node *newNode)
{
Node *currentNode = myTree->root;
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = currentNode->leftChild;
}
}

need to get the parent pointer value, whats the best way to do it

typedef struct node_ {
avl_node node;
some_struct *data;
}node_t;
Now if a function(API) returns me the pointer to data is there a way, I can get the structure node_t pointer?
For example:
node_t *a = malloc(sizeof(node_t));
a->data = malloc(sizeof(some_struct));
//some code
//a->data->key = some_val;
//avl_insert(a->data->key)
/* API to get the data, which return pointer of type some_struct*/
some_struct *temp;
temp = get_data(key)
Is there a way for me to get the the pointer node_t of the "temp".
Please, let me know what's the best way to get it.
If you need to get back to the node that contains the data, you have to build the association yourself. Perhaps the most straightforward way is to extend some_struct:
typedef struct my_some_struct {
some_struct ss;
struct node_ *back;
} my_some_struct;
typedef struct node_ {
avl_node node;
my_some_struct *data;
}node_t;
node_t *a = malloc(sizeof(node_t));
a->data = malloc(sizeof(my_some_struct));
a->data->back = a;
my_some_struct *temp;
temp = get_data(key);
some_struct *ss = &temp->ss;
node_t *back = tmp->back;
Alternatively, you can extend the AVL tree with an API to return the node_t * for a given key.
node_t *n = get_node(key);

Initialize and get struct variables in another struct?

Hey guys I have two structs: one is a key-pair and the other is a node.
typedef struct {
char *key;
void *value;
} VL;
typedef struct node{
struct node *left;
struct node *right;
VL data;
} BST;
How would I go about initializing the node struct and adding the VL struct inside?
This is what I have so far:
// Create new node
struct node *temp = malloc(sizeof(node));
temp->left = NULL;
temp->right = NULL;
struct VL *vl = malloc(sizeof(VL));
vl->key = key;
vl->value = &value;
temp->data= *vl;
And I've also tried many other things like setting temp->data.key to key etc, all of which return errors. So I've come here for help :).
Also how would I go about getting the data from the nodes?
char *key = (char *)5;
void *val = "hello";
// create node with this key/val pair and insert into the tree, then print
printf("key = %d; value = %s\n", (int)head->data.key, (char*)head->data.value);
Would that suffice?
Thanks!
The memory for VL data is allocated as part of the node struct and does not need to be reallocated.
Try:
struct node *temp = malloc(sizeof(node));
temp->left = NULL;
temp->right = NULL;
(temp->data).key = key;
(temp->data).value = &value;

List within a Tree?

A small query really with reference to Structs.
If I had a
Struct Node {
char *number;
struct Node *next;
}List;
and a tree Structure:
struct Node {
char *name;
char *number;
struct Node *right;
struct Node *left;
};
and I wanted to design it, such that each Node within my Tree, can each contain a LIST of Phone Numbers, is there a way in which I can do this, and if so, how exactly can I reference my struct List within my Tree?
EDIT:
Any ideas as to why this is seg faulting? Using the Structs recommended below.
TreeNode* AddNode(TreeNode *root, ListNode *list, char *name, char *phonenum) {
int comparison;
if ( root == NULL ) {
root = (TreeNode *)malloc(sizeof(TreeNode));
list = (ListNode *)malloc(sizeof(ListNode));
root->name = strdup(name); root->list->number = strdup(phonenum);
root->left = root->right = NULL;
You'd simply do it like so:
typedef struct Node {
char* name;
List* list;
struct Node *right;
struct Node *left;
} Node;
Then in order to get a local copy of the first element of the list in each node, you'd do something like the following:
Node* treenode; //this is pointing to some node in the tree
char* num_buffer = strdup(treenode->list->number);
//use num_buffer and then call free() on it when you're finished
If you wanted to get a number that was not the first number in the list, you would have to create a search function for your linked list.
Can you do something like this?
typedef struct ListNode
{
char *number;
struct ListNode *next;
} ListNode;
typedef struct TreeNode
{
char *name;
ListNode *numbers;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;

Resources