So I'm having a problem with memory leaks in my program. One of my functions free_stack is suppose free all the memory in the stack and the stack should not be used after this function call. My other problem is in my reset_stack function which is suppose to free any memory not in use anymore. The stack can be used after the function call and the function is also suppose to reset the stack to its original contents in *make_stack.My program is not doing this. Here's my code.
struct int_stack *make_stack(int node_capacity){
struct int_stack *stk = malloc(sizeof(struct int_stack));
struct is_node *head = malloc(sizeof(struct is_node));
head->contents = malloc(node_capacity * sizeof(int));
head->next_index = 0;
head->next = NULL;
stk->node_capacity = node_capacity;
stk->head = head;
stk->size = 0;
return stk;
}
void free_stack(struct int_stack *stk) {
while(stk->head->next != NULL) {
free(stk);
}
}
void reset_stack(struct int_stack *stk) {
free_stack(stk);
*make_stack(stk->node_capacity);
}
calling free doesn't do anything to your allocated memory, and also value of pointers you called free on. And also your function *make_stack(stk->node_capacity); returns pointer to the newly allocated stack, use that. stk = *make_stack(stk->node_capacity);.
Related
I'm very new to C and I'm trying yet to fully understand it. I implemented a stack
but found trouble when making its destructor and it constructor/init.
Are these well done?
These are the typedefs for the structures used by the stack:
typedef struct Node{
void* cargo;
struct Node* next;
}Node;
typedef struct Stack{
int size;
Node* firstOut;
}Stack;
And these are the functions:
void newStack(Stack* stack){
stack = (Stack*)malloc(sizeof(Stack));
stack->firstOut = NULL;
stack->size = 0;
}
void freeStack(Stack** stack){
empty((*stack));
free((*stack)->top);
(*stack)->size = 0;
free(stack);
}
My question is: are they well done? How would someone with proper experience do it?
newStack should simply return the stack pointer that it allocates. It doesn't need to receive a Stack* as an argument.
stack *newStack() {
Stack *stack = malloc(sizeof(Stack));
if (stack != NULL) { // allocation successful
stack->firstOut = NULL;
stack->size = 0;
}
return stack;
}
and freeStack should receive a stack pointer as argument, it doesn't need double indirection.
void freeStack(Stack *stack) {
empty(stack);
free(stack->firstOut); // This isn't done by empty()?
free(stack);
}
There's no need to set stack->size before freeing, since the memory is going to go away and the value it contains is irrelevant.
I'm having a little trouble understanding an example function my professor has given as an example for linked lists. It seems that the memory allocated is not actually in the scope of main. But it seems to work. Here are the example functions:
#define NEW(x) (x*)malloc(sizeof(x))
NODE *make_node (void *data) {
NODE *temp;
temp = NEW(NODE);
if (temp != NULL) {
temp->data = data;
temp->next = NULL;
}
return temp;
}
int insert_at_tail(ROOT *r, DATA *d) {
NODE *temp;
temp = make_node(d);
if (temp == NULL) // fail, cannot create new NODE
return -1;
if (r == NULL) {
r = make_root();
if (r == NULL) // fail, cannot create ROOT
return -1;
}
(r->num)++;
if (r->num == 1) { // if previously the list is empty
r->head = r->tail = temp;
}
else {
r->tail->next = temp;
r->tail = temp;
}
return 0;
}
It seems to me that the function insert_at_tail calls the make_node function which then returns a memory location in the function insert_at_tail. But that memory location is in the scope of that function? The memory is then assigned to linked list data. How is it that when in the main function the linked list data can still access that memory? I thought malloc was not global. Thanks for reading! Hopefully someone can help my confusion.
malloc is how you allocate heap memory; the allocated memory sticks around until the pointer is explicitly free-ed. Anyone with access to that pointer can use it until the pointer is passed to free.
malloc isn't "global" in the sense that it can return pointers to memory that isn't preallocated in global space, but that doesn't mean the memory it allocates is disposed of automatically when the scope in which malloc was called exits.
When I try to free an allocation in a struct inside a struct, I get an error.
How can I fix it?
typedef struct card
{
char* sign;
char* color;
int number;
char* name;
}card;
typedef struct deck
{
card data;
deck* next;
}deck;
deck* deleteHead(deck* head)
{
deck* curr = head;
if (head==NULL)
return head;
curr=curr->next;
if(head->data.color!=NULL)
free(head->data.color);//error
if(head->data.name!=NULL)
free(head->data.name);//error
if(head->data.sign!=NULL)
free(head->data.sign);//error
free(head);//ok
return curr;
}
when I'll delete the errors and only freeing the head - it'll work, but when I'll try to delete the allocations inside the head, I'll get a run time error.
How can I solve this?
Thank you in advance.
You probably did not initialize the pointers in the card structure. These should either be initialized to NULL or to a pointer to memory allocated by malloc, calloc or strdup.
Also note that you don't need to test pointers against NULL before calling free(). free(NULL); will gracefully return immediately, it is legal to call free with NULL. Incidentally it is also legal in C++ to delete a null pointer.
The function can be further simplified this way:
deck *deleteHead(deck *head) {
deck *next = NULL;
if (head != NULL) {
next = head->next;
free(head->data.color);
free(head->data.name);
free(head->data.sign);
free(head);
}
return next;
}
The function free can only de-allocate a block of memory previously allocated by a call to malloc, calloc or realloc. Your code will run without any runtime error if you initialize it properly. Here's a sample code:
int main()
{
deck* root = (deck*)malloc(sizeof(struct deck));
root->card.color = strdup("color");
root->card.name = strdup("name");
root->card.sign = strdup("sign");
root->card.number = 2;
root->next = NULL;
root = deleteHead(root);
return 0;
}
And also there is a slight correction in your code:
typedef struct deck
{
card data;
struct deck* next;
}deck;
I am currently working on stacks right now. I am supposed to use the following structures and function prototypes:
typedef struct node_{
char data;
struct node_ *next;
}node;
typedef struct stack_{
unsigned int size;
node* stack;
}stack;
stack* create_stack();
void push(stack* s, char val);
Here is my actual code for create_stack() and push():
stack* create_stack()
{
stack *stack;
stack = malloc(sizeof(stack));
stack->size = 0;
stack->stack = NULL;
return stack;
}
void push(stack* s, char val)
{
stack *newStack;
newStack = create_stack();
newStack->stack->data = val;
newStack->stack = s->stack;
s = newStack;
}
I am getting a segmentation fault when I try to store char val into newStack->stack->data. How does this not work? What do I need to do to make this stack on top???
The push function is wrong.
void push(stack* s, char val)
{
stack *newStack;
newStack = create_stack(); /* new stack created, why not work on the existing one ? */
newStack->stack->data = val; /* you're writing to a NULL pointer */
newStack->stack = s->stack;
s = newStack; /* this will not be visible from outside the function */
}
First of all, you are trying to recreate a new stack for each call of this function, which is certainly not what is intended.
If you try to modify the value of s, it will not be visible from outside the function, and you will still have your original stack.
Then, you are accessing the stack->data member even though stack has no space allocated to it yet (because you set it to NULL). You actually set it right after, which is why it crashes, most probably.
You probably want to do something like this:
void push(stack* s, char val)
{
node * n;
/* go to the end of the "stack" */
n = s->stack;
while (n != NULL) {
n = n->next;
}
/* allocate memory for a new node */
n = malloc(sizeof(node));
/* initialize node */
n->data = val;
n->next = NULL;
/* increment stack size */
s->size++;
}
And as mentionned before, this is merely a singly-linked list which is not the best fit for a stack, because as it exists now, you have to follow the node pointers to reach the last element, which makes push and pop operations O(N).
A faster implementation would look like this:
void push(stack* s, char val)
{
node * first_node, * new_node;
first_node = s->stack;
/* allocate memory for a new node */
new_node = malloc(sizeof(node));
/* initialize node */
new_node->data = val;
new_node->next = first_node;
/* increment stack size */
s->stack = new_node;
s->size++;
}
The top of the stack is always the first node, and the performance is O(1).
Follow your code....
stack *newStack = create_stack(); // in push()
newStack = malloc(sizeof(stack)); // in create_stack()
newStack->stack = NULL; // in create_stack()
newStack->stack->data = val; // in push()... this is where you crash.
Because newStack->stack is a NULL pointer. Your create_stack() function sets it to NULL, and you then dereference it. You have to allocate a struct node somewhere.
This code also has some readability issues which might be contributing to the problem. You are naming variables the same names as their types, which is very confusing. Consider using some other naming pattern like stack_t for types and stack for variable names.
After more than 10 years of having the luxury of using garbage collected languages, I am returning to C99 and obviously I am having difficulties with memory management.
I have a linked list consisting of stack items and a type Stack which points to the address of the first element of this list.
This is my code so far:
#include <stdio.h>
#include <stdlib.h>
typedef struct StackItem
{
int head;
struct StackItem* next;
} StackItem;
typedef StackItem** Stack;
StackItem* makeStackItem (int head)
{
StackItem* a = (StackItem*) malloc (sizeof (StackItem) );
a->head = head;
a->next = (StackItem*) 0;
return a;
}
Stack makeStack ()
{
Stack stack = (Stack) malloc (sizeof (StackItem*) );
*stack = (StackItem*) 0;
return stack;
}
void pushStack (StackItem* item, Stack stack)
{
item->next = *stack;
*stack = item;
}
void freeStack (Stack stack)
{
StackItem* current = *stack;
StackItem* next;
while (current != 0)
{
next = current->next;
free (current);
current = next;
}
free (stack);
}
int main ()
{
Stack stack = makeStack ();
for (int i = 0; i < 10; i++)
pushStack (makeStackItem (i), stack);
printf ("Here be dragons.\n");
freeStack (stack);
return 0;
}
My questions are:
Are the first lines of makeStack and makeStackItem sensible and
necessary?
Is the last line of freeStack sensible and necessary?
Once main returns, have I freed all the memory previously
allocated?
How can I see whether I have memory leaks or not?
Thank you very much in advance.
Are the first lines of makeStack and makeStackItem sensible and necessary? yes except for the casting malloc issue
Is the last line of freeStack sensible and necessary? yes
Once main returns, have I freed all the memory previously allocated? yes
How can I see whether I have memory leaks or not? use valgrind
I would toss the casts of 0 too.