Hello:
I have a question regarding struct when making hash buckets eg.
typedef struct _hashNode
{
void *key;
void *value;
struct _hashNode *next;
} hashNode;

let's say when I create the table:

hashNode *nodeList = (hashNode *)malloc(sizeof(hashNode) * 200);

This is because I want a fixed list size and then each of these array spots will be a linked list or "buckets" for inserting values downwards. (I hope you understand this) Anyways, if I were to insert values into lets say nodeList[5]->key, would I have to allocate memory to key

eg. nodeList[5]->key = (void *)malloc(sizeof(void) +1);

Or does that automatically do that when I allocate memory to the nodeList[5].

thanks

Dani AI

Generated

Short answer for : allocating an array of hashNode gives you space for each node's pointer fields, but it does not allocate memory for the data those pointers reference. Storing a pointer into a struct just copies the pointer value; it does not create a copy of the pointed-to bytes. That means you do not need a separate allocation just to hold the pointer itself, but you must decide who owns the pointed memory and how long it will remain valid.

Practical guidance:

  • If the node should own the key (safe option), allocate the exact number of bytes required for the key (for C-strings that is length+1; for binary blobs use the known size), copy the bytes, and store the pointer in the node. Keep the length somewhere (add a size field) so you can free() correctly later. Never try to use a size like sizeof(void) — determine the real byte count. Check allocation results and free previous key before replacing it to avoid leaks.
  • If you only want a shallow store (just keep caller's pointer), document that clearly and ensure the caller's buffer outlives the node to avoid dangling pointers.
  • For strings you can use helper functions (where available) that duplicate strings; for C++ prefer std::string, std::vector, or standard containers instead of manual malloc/free.

Notes on replies: was right to highlight dot vs arrow for array elements; 's wording is a useful intuition but remember the difference between "space for a pointer" (allocated with the struct) and "space for the data the pointer names" (not allocated). 's point about allocation style is valid — prefer language-appropriate allocation and be cautious about casting malloc in C.

Checklist before insert: decide ownership, compute exact byte count, allocate & copy if owning, store size, and always free on removal.

Recommended Answers

All 4 Replies

Or does that automatically do that when I allocate memory to the nodeList[5].

No, you need to do that.

[edit]
Except that this won't go far: sizeof(void) -- you need a type to have a size of that type.
[/edit]

Why the casts on malloc ? If you're using C++, why not new or a vector ? If C, stop doing that and let your compiler help you write better code.

The purpose of malloc is dynamically, key word, dynamically allocate memory from the preprocessor for a DATA structure.

In this case hashNode or whatever is your data structure, so you would be mallocing a pointer to an array of hashNode structures. Each of these hashNodes have the elements you specified under the structure definition. They each have a keys, and so forth, without further mallocing.

Now if you wanted a malloc'd array of hashNodes and a malloc array of keys, that would be a little difficult to handle with, but I guess it could be possible, althought it is definately poor code.

malloc is a data structure preprocessor function, keep this in mind. It will not change or modify the elements in the data structure, it simply allocates memory.

Hope this helps,

Mistro116

The thing is I am setting node[5]->key for example to another pointer eg. void *key. So something like this: node[5]->key = key. I am setting the pointer in the typedef struct to the pointer void *key which is an argument/parameter in the function header.

eg. void *insert(void *key)
{
node[5]->key = key;
}

node is global.

If done this way I don't have to allocate memory to node[5]->key before setting it equal to key right?

node[5]->key = key;

That is wrong syntax. you have to use dot notation, not pointer notation because node[5] is NOT a pointer.

node[5].key = key;

If done this way I don't have to allocate memory to node[5]->key before setting it equal to key right?

Well, maybe yes and maybe no. How is paramater key being allocated? Will the calling function reuse that memory for something else, such as does it get overwritten each time the insert function is called or is new memory allocated each time?

I find it normally best to reallocate the memory so that node has complete control over it and not count on some other function allocating/deallocating node's memory.

eg. void *insert(void *key, long keysize)
{
node[5].key = malloc(keysize);
memcpy(node[5].key,key,keysize);
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.