C dynamic allocate chunk of memory - c

Here is my data structure
struct Node{
int x;
Node *next;
Node *prev;
}
If I allocate memory
Node *A = malloc (sizeof (Node) * 10);
How can I access each box in the array using array index in this case? or it's not possible?
My goal just want to make a linked list in this chunk of memory.
basically i want to assign a block of memory and then assign their prev and next....
maybe it's confusing , sorry about my wording..

This gives you an array of 10 Nodes, accessible through A. Now, all you have to do is e.g.
A[0].next = &A[1];
to set the next value of the first node.

malloc returned void* then you should cast it for your type Node*
Node *A = (Node *)malloc (sizeof (Node) * 10);

Allocating many nodes the way you do may efficient for memory management but I wouldn't access them like an array. I think you should rely on the linked list and not mix the the two methods since it would easily lead to bugs hard to trace and evn harder to fix.

Related

Freeing a pointer to structure containing an array

I have some issues, maybe coming from a misunderstanding of how the function "free" works.
Basically I have defined a structure like this
typedef char parola[11]
typedef struct _node node
struct _node
{
parola wrd;
node *padre;
node *Ts;
node *Td;
};
Later in the code I allocate memory for a node using malloc:
node *r
r = (node *) malloc(sizeof(node));
And i create binary search trees allocating memory for every single node in this way.
When I try to remove a node in a bst, I pass a pointer to that node *n. I think I nail the recursive procedure, but then when it comes to using free() on the pointer to the node, that doesn't seem to work. I am sure of it because if I try to print "parola" in the node, it does actually print the word that was contained there after deallocating the memory.
node *n
.../*in another function*/
free (n)
printf("%s\n",n->wrd)
/*This does print the word inside the node after the deallocation*/
What am I missing here? Do i need to use free() in a different way?
Thanks for your help.
In C, free doesn't wipe the data. It just says "I'm not using it any more; you can use it for something else." If nothing needs to use it in that time, it won't be overwritten.
However, you can't guarantee that it won't be overwritten. Using stuff after it's freed is an excellent way to have your program suddenly, unpredictably fail at the worst possible moment.
(Make sure you free the node(s) you're pointing to before you throw away (or free) their last pointer(s), and make sure you only free each thing once!)

Is freeing a dynamically allocated array same as freeing a linked list?

Suppose I have a struct that looks like this:
typedef struct node{
char **word_ptrs;
int value;
struct node *next;
} Node;
and I have dynamically allocated spaces for the linked list, as well as the word_ptrs within this struct.
For example:
Node *head = malloc(sizeof(Node)); // not important, what I care is not this node.
head->word_ptrs = malloc(10 * sizeof(Node)); // I care about this.
My question is: I know how to free the linked list, but I feel confused when I try to free the dynamically allocated array. When I try to free the array above, should I just directly free the entire array? Or I should go to free every single char * within that array?
Thanks.
You should only pass to free what was returned from malloc.
In this case, you make one allocation for an array of char *, so you do a single free to clean it up. Also, the amount of space you're allocating is 10 * sizeof(Node), but it should be 10 * sizeof(char *).
That depends on where those pointers came from, and who owns them.
If they were dynamically allocated and the node owns them, then you should free them before freeing the array.
If they were dynamically allocated but owned elsewhere, their respective owners should free them later.
If they were not dynamically allocated, you mustn't free them at all.
If you have a combination of the three, you're in trouble.
You should also allocate it with sizeof(char*), or sizeof(*head->word_ptrs), not sizeof(Node).
Although, if the size is always ten, you might as well use an array:
typedef struct node{
char *word_ptrs[10];
int value;
struct node *next;
} Node;

If you malloc a struct* does it create local variables?

Feel free to edit the title if it doesn't make sense. So I've been using malloc for a while without really being completely sure of how it works. If I create an int pointer and set it equal to malloc(10*sizeof(int), I figure that it allocates a block in memory of 10 times the size of one int, then returns the starting address of this allocation, but nothing is actually initialized within that memory yet. Am I OK so far?
Now say I create a struct for linked list nodes like this:
typedef struct node_ {
int data;
struct node_ *next;
} Node;
and then have a create linked list function:
Node* LLCreate(int data) {
Node *head = malloc(sizeof(Node));
if ( head != NULL) {
head->next = NULL; // don't get how malloc created `next`
head->data = data; // or `data`
}
return head;
}
What I don't get, and can't seem to google appropriately, is, if head is just the starting location in memory of an empty block of size Node, and not an actual variable, how does it have the local variables of next and data?
Maybe this is a nonsensical question because I have some fundamental misunderstanding of what's going on here, but if anyone understands what I'm trying to ask and could clear this up for me I'd really appreciate it.
It doesnt have local variables like next and data.
next and data are just used to calculate the address relative to from where node is pointing.
When you do node->data then the address is calculated as address pointed by node + (total bytes required by any metadata for malloc) + 0 because data is the first member of node struct.
And when you do node->next then the address is calculated as address pointed by node + (total bytes required by any metadata for malloc) + sizeof(data) , because next is the second member of the node struct that comes after data member.

Allocate a consecutive linked list in c

Im trying to create a linked list in c. The twist is that I want to allocate the memory for the list so that all the nodes are consecutively stored in memory.
Maybe an array structure is the way to go.
Any ideas?
The obvious way would be to allocate a number of nodes in a block, then link them together into a free list. When you need to add a node to your linked list, you'll grab the one from the head of your free list. When you want to delete a node, you link it back onto the free list:
struct node {
struct node *next;
// other data here.
};
node *free_list;
#define block_size 1024
void initialize() {
free_list = malloc(block_size * sizeof(struct node));
for (i=0; i<block_size-1; i++)
free_list[i].next = &free_list[i+1];
free_list[block_size-1].next = NULL;
}
struct node *alloc_node() {
struct node *ret;
if (free_list == NULL)
return NULL;
ret = free_list;
free_list = free_list->next;
return ret;
}
void free_node(struct node *n) {
n->next = free_list;
free_list = n;
}
If you're looking at a linked list, don't worry about where in memory they are. That's what the pointers on the nodes are for.
If you want them sequential, allocate an array.
Yes, use an array. More interesting is why you want this. If your program requires this to work, then you'll need to make sure your array is big enough to store all the nodes that might be allocated. If not, you can allocate batches of nodes.
FYI. I've seen this strategy used in the past on the assumption that sequentially allocated nodes would result in fewer cache misses when searching the list. In the system of interest, that didn't actually give much a performance improvement. [ Not enough profiling of course!.]
You could do something like this
struct node
{
int data;
struct node *next;
};
struct node linkedlist[50];
This would allocate space for linked list structure in contiguous locations.

What are some useful examples of malloc() in C?

I'm just reading about malloc() in C.
The Wikipedia article provides an example, however it justs allocate enough memory for an array of 10 ints in comparison with int array[10]. Not very useful.
When would you decided to use malloc() over C handling the memory for you?
Dynamic data structures (lists, trees, etc.) use malloc to allocate their nodes on the heap. For example:
/* A singly-linked list node, holding data and pointer to next node */
struct slnode_t
{
struct slnode_t* next;
int data;
};
typedef struct slnode_t slnode;
/* Allocate a new node with the given data and next pointer */
slnode* sl_new_node(int data, slnode* next)
{
slnode* node = malloc(sizeof *node);
node->data = data;
node->next = next;
return node;
}
/* Insert the given data at the front of the list specified by a
** pointer to the head node
*/
void sl_insert_front(slnode** head, int data)
{
slnode* node = sl_new_node(data, *head);
*head = node;
}
Consider how new data is added to the list with sl_insert_front. You need to create a node that will hold the data and the pointer to the next node in the list. Where are you going to create it?
Maybe on the stack! - NO - where will that stack space be allocated? In which function? What happens to it when the function exits?
Maybe in static memory! - NO - you'll then have to know in advance how many list nodes you have because static memory is pre-allocated when the program loads.
On the heap? YES - because there you have all the required flexibility.
malloc is used in C to allocate stuff on the heap - memory space that can grow and shrink dynamically at runtime, and the ownership of which is completely under the programmer's control. There are many more examples where this is useful, but the one I'm showing here is a representative one. Eventually, in complex C programs you'll find that most of the program's data is on the heap, accessible through pointers. A correct program always knows which pointer "owns" the data and will carefully clean-up the allocated memory when it's no longer needed.
What if you don't know the size of the array when you write your program ?
As an example, we could imagine you want to load an image. At first you don't know its size, so you will have to read the size from the file, allocate a buffer with this size and then read the file in that buffer. Obviously you could not have use a static size array.
EDIT:
Another point is: When you use dynamic allocation, memory is allocated on the heap while arrays are allocated on the stack. This is quite important when you are programming on embedded device as stack can have a limited size compared to heap.
I recommend that you google Stack and Heap.
int* heapArray = (int*)malloc(10 * sizeof(int));
int stackArray[10];
Both are very similar in the way you access the data. They are very different in the way that the data is stored behind the scenes. The heapArray is allocated on the heap and is only deallocted when the application dies, or when free(heapArray) is called. The stackArray is allocated on the stack and is deallocated when the stack unwinds.
In the example you described int array[10] goes away when you leave your stack frame. If you would like the used memory to persist beyond local scope you have to use malloc();
Although you can do variable length arrays as of C99, there's still no decent substitute for the more dynamic data structures. A classic example is the linked list. To get an arbitrary size, you use malloc to allocate each node so that you can insert and delete without massive memory copying, as would be the case with a variable length array.
For example, an arbitrarily sized stack using a simple linked list:
#include <stdio.h>
#include <stdlib.h>
typedef struct sNode {
int payLoad;
struct sNode *next;
} tNode;
void stkPush (tNode **stk, int val) {
tNode *newNode = malloc (sizeof (tNode));
if (newNode == NULL) return;
newNode->payLoad = val;
newNode->next = *stk;
*stk = newNode;
}
int stkPop (tNode **stk) {
tNode *oldNode;
int val;
if (*stk == NULL) return 0;
oldNode = *stk;
*stk = oldNode->next;
val = oldNode->payLoad;
free (oldNode);
return val;
}
int main (void) {
tNode *top = NULL;
stkPush (&top, 42);
printf ("%d\n", stkPop (&top));
return 0;
}
Now, it's possible to do this with variable length arrays but, like writing an operating system in COBOL, there are better ways to do it.
malloc() is used whenever:
You need dynamic memory allocation
If you need to create array of size n, where n is calculated during your program execution, the only way you can do it is using malloc().
You need to allocate memory in heap
Variables defined in some functions live only till the end of this function. So, if some "callstack-independent" data is needed, it must be either passed/returned as function parameter (which is not always suitable), or stored in heap. The only way to store data in heap is to use malloc(). There are variable-size arrays, but they are allocated on stack.

Resources