Problems with pointer into structure - c

The memory has not been freeded
Please some help with this problem
#include <stdio.h>
#include <stdlib.h>
typedef struct paramint
{
short val;
char name[150 + 1];
}tParamint;
int main(int argc, char *argv[]) {
tParamint *e;
e=(tParamint*)malloc(2*sizeof(tParamint));
e[1].val=12;
e[2].val=13;
printf("e[1].val=[%d]\n", e[1].val);
printf("e[2].val=[%d]\n", e[2].val);
free(e);
printf("e[1].val=[%d]\n", e[1].val);
printf("e[2].val=[%d]\n", e[2].val);
return 0;
}
Initial value:
e[1].val=[12]
e[2].val=[13]
After free
e[1].val=[12]
e[2].val=[13]

From the reference
There are two points
A block of memory previously allocated by a call to malloc, calloc or realloc is deallocated, making it available again for further allocations.
Notice that this function does not change the value of ptr itself, hence it still points to the same (now invalid) location.
So the memory you just freed, are not deallocated immediately, it just marked as re-allocatable and your ptr is pointing to those invalid location. So it's a good idea to de-referencing the ptr to null just after freeing the ptr.
By de-referencing the ptr to null after you also make sure that, you are not freeing the same memory more than once.

Related

munmap_chunk(): invalid pointer, when to use free()

I'm curious as to why free(myWord->w) would be an invalid pointer? I allocate memory to it, so shouldn't I free it as well? or does freeing a struct also free all of its fields?
New to C so any insight on the world of pointers is much appreciated!
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct word {
char *w;
} WORD;
void setWord(char **f);
int main() {
WORD *myWord = malloc(sizeof(WORD));
myWord->w = malloc(6);
strcpy(myWord->w, "hello"); // set to "hello"
setWord(&(myWord->w)); // set to "bagel"
free(myWord->w); /* munmap_chunk(): invalid pointer. Aborted (core dumped) */
free(myWord);
return 0;
}
void setWord(char **F) {
*F = "bagel";
}
*F = "bagel"; is not how you assign a string. Instead the code overwrite the value of the pointer myWord->w so when you call free, it's no longer the correct pointer value.
To see that the pointer change, try this:
printf("%p\n", (void*)myWord->w);
setWord(&(myWord->w)); // set to "bagel"
printf("%p\n", (void*)myWord->w);
Consequently, the free call will fail as the pointer-value isn't the one you got from the malloc.
So instead of *F = "bagel"; use
strcpy(*F, "bagel"); // NOT: *F = "bagel"
Further you don't need to pass the address of w. Simply do:
void setWord(char *F) {
strcpy(F, "bagel");
}
and call it like:
setWord(myWord->w);
And...
I allocate memory to it, so shouldn't I free it as well? or does freeing a struct also free all of its fields?
Yes, you must free it.
No, free of a struct does not free members automatically. You must do that.

Why am I receiving invalid pointer error when running this code

I am receiving the following error when running this code.
Error in `main': free(): invalid pointer:
My idea is to use a pointer allocated through malloc. This is a sample code.
Please let me know why I am receiving this error.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c=10;
int* ptr = NULL;
ptr = (int*)malloc(sizeof(int));
if(ptr == NULL)
{
printf("Memory not allocated");
exit(0);
}
ptr = &c;
free(ptr);
ptr=NULL;
}
int c=10;
Variable c allocated on the stack.
ptr = (int*)malloc(sizeof(int));
Assign address of allocated memory on the heap to ptr
ptr = &c;
Assign address of c to ptr.
You have two problems in your code.
Memory Leak. You have lost address of allocated memory since you used reassign of ptr. In this case you don't have any other way to free memory allocated on the heap until program ends.
You can't free memory allocated on the stack with free() function. It's auto variables
So, If you were trying to assign the value of c to the allocated space:
*ptr = c;
Why am I receiving an invalid pointer error?
Because you free a pointer that was not allocated with malloc (or realloc).
You have a memory leak, i.e. you lose a malloced pointer with ptr = &c, which assigns the address of c to ptr, losing the value returned by malloc.
Well to do that you need to allocate for a pointer of pointer like this
#include <stdio.h>
#include <stdlib.h>
int main() {
int c=10;
int** ptr = NULL;
ptr = (int**)malloc(sizeof(int*));
if(ptr == NULL)
{
printf("Memory not allocated");
exit(0);
}
*ptr = &c;
free(ptr);
ptr=NULL;
}
the problem in your case that you are freeing a non dynamic allocated memory and that gives you an error, and even in other cases you should always keep the address of the allocated memory to free it when you no more need it for example
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr1 = (int*)malloc(sizeof(int));
int *ptr2 = (int*)malloc(sizeof(int));
*ptr1 = 5;
*ptr2 = 10;
// this is wrong because now there is no way to free
// the address of the allocated memory to ptr1
ptr1 = ptr2;
free(ptr1);
// this gives an error because ptr2 is already free
free(ptr2);
}
Conclusion:
If you want to allocate to store a pointer, then you need to allocate for a pointer to pointer, so the pointer of the allocated memory stay so you can free that memory when you no longer need it

Why only one free() works for this segment of code?

I use free() to free the structure I allocated before, and I want to test if they have successfully free, but I get only one of them free why?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct student{
char *name;
struct student *next;
}student;
int main(int argc, const char * argv[]) {
student *a=malloc(sizeof(student));
a->name="echo";
student *b=malloc(sizeof(student));
b->name="harry";
a->next=b;
b->next=NULL;
free(a);
free(b);
printf("%s\n", a->name);
printf("%s\n", b->name);
return 0;
}
and I got this output.Why?
(null)
harry
Program ended with exit code: 0
You can't "test" if they have successfully been freed, trying to access any memory that has been freed is undefined behavior, instead of testing just accept and move on.
You have freed the memory but that doesn't mean the pointer has been invalidated by the system. In your second case, the data where it pointed to has not yet been re-used so printf finds it and can print.
In the first case the memory has been re-used or reset. print finds a null pointer.
In the second case the memory has not yet been re-used: printf finds it and can print it.
But this undefined behavior and anything could have happened.
You can better use free along with setting the variable to NULL.
free(b);
b = NULL;
free(a);
a = NULL;
When you call free, the variable is marked for recollection. And when that recollection of the memory allocated should happen is up to the underlying OS. You should not access the freed block.

Will freeing a structure pointer also free the memory allocated inside of the structure in C?

For example I have this structure:
typedef struct{
char *var = (char*)malloc(20*sizeof(char));
} EXAMPLE;
EXAMPLE *point = (EXAMPLE*)malloc(sizeof(EXAMPLE));
My first question is, will the memory allocated inside the structure only be allocated when I allocate memory for the EXAMPLE pointer?
My second question, when I use free(point) will the memory allocated for var also be freed?
With this struct:
typedef struct{
char *var;
} EXAMPLE;
Remember that when you allocate space for the struct, you're allocating space only for the char * pointer. This pointer just points to memory elsewhere. When you free() the struct, you're just freeing the char * pointer, not the actual memory that it points to.
As such, if you make this struct and then malloc() space for the string you want var to point to, you need to free() the string as well as free()ing the struct.
Some code demonstrating how this might work:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct {
char *var;
} EXAMPLE;
int main(int argc, char *argv[]) {
// malloc() space for the EXAMPLE struct.
EXAMPLE *point = malloc(sizeof(EXAMPLE));
// malloc() space for the string that var points to.
point->var = malloc(20 * sizeof(char));
// Copy "Hello!" into this memory (care with strcpy).
strcpy(point->var, "Hello!");
// Print it, it works!
printf("point->var is: %s\n", point->var);
// Free stuff.
free(point->var);
free(point);
return 0;
}
Also note that we don't cast the result of malloc(), in C you're not meant to. Also note that we free() point->var first before point. This is important because if we free() point first, we lose the pointer to point->var, and we have a memory leak.
I'm ignoring the non-compiling code since the question is pretty clear without it ;-)
No. free() does not know the structure of what it is pointing at,so it just frees one "block". If that block has pointers to other malloced memory then they are leaked (unless there is a pointer to those blocks somewhere else).

Pointers and malloc.... Wrong in this code snippet

#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr = NULL;
ptr = (int*)malloc(2*sizeof(int*));//memory allocation dynamically
return 0;
}// What is the error in this type of allocation
I guess you want allocate the space for 2 ints (not 2 pointers to int):
int *ptr = malloc(2*sizeof(int));//memory allocation dynamically
You would have understood that if you read the compilation error carefully.
int *ptr = NULL;
ptr = (int*)malloc(2*sizeof(int*)); //wrong
The above code is wrong. It should be:
ptr = malloc(2*sizeof(*ptr));
No need to cast the return value of malloc. void * will be safely casted. Additionally, using sizeof(*ptr) is easier to maintain in case ptr's data type needs to be modified.
Also, free dynamically allocated memory when its no longer needed or you will have memory leak.
free(ptr);
The problem lies at sizeof(int*)) and it should be sizeof(int))
Dynamic allocation requires you to tell what size of bytes you want it to allocate, and for that reason in this example you should use sizeof(int).

Resources