Search code examples
cexc-bad-accessmemcpy

EXC_BAD ACCESS in memcpy


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;
};

Solution

  • 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.