Trying to free reallocated memory gives free(): invalid pointer - c

I can't figure out why I am getting the error free(): invalid pointer when running this code. I thought p is going to point to a block of memory set aside for the structures, so I am trying to free pointers beginning from the p e.g. p+1, but this is no good. What am I missing here?
#include <stdio.h>
#include <stdlib.h>
struct s {
int x;
};
int main()
{
struct s *p = NULL;
for (int i = 0; i < 3; i++) {
if ((p = realloc(p, (i+1) * sizeof(struct s))) != NULL) {
struct s x = {.x=i*10};
*(p+i) = x;
} else exit(EXIT_FAILURE);
}
for (int i=0;i<3;i++) {printf("%d ", (p+i)->x);}
//free(p);
free(p+1);
//free(p+2);
return 0;
}

Before the loop you declared the pointer p
struct s *p = NULL;
So after the loop it will store the address of the last reallocated memory.
To free the allocated memory you need just to write
free( p );
The expression p + 1 points to the second element of the dynamically allocated array that was not allocated dynamically. It is the whole array that was allocated dynamically.

Related

Regarding free function in c

May I know that if I free something in C programming language and I declare it as pointer before, it would just free out the memory but the pointer is still there or the pointer data type will also be destroyed as the code below. Also, may I know that if I want to free up my memory in this situation, why would I use free(list) in the end instead of using free(tmp)? Below is my code:
#include <stdio.h>
#include <stdlib.h>
int main(void){
int *list = malloc(3 *sizeof(int));
if (list==NULL){
return 1;
}
list[0] = 1;
list[1] = 2;
list[2] = 3;
int *tmp = malloc(4 * sizeof(int));
if (tmp==NULL){
free(list);
return 1;
}
for (int i = 0; i < 3; i++){
tmp[i] = list[i];
}
tmp[3] = 4;
free(list);
list = tmp;
for (int i = 0; i < 4; i++){
printf("%i\n", list[i]);
}
free(list);
}
Calling free does not affect the pointer or its contents, just what the pointer pointed to. But the value in that pointer should no longer be considered valid.
The part about your specific use of free was addressed in the comments.
In these declarations
int *list = malloc(3 *sizeof(int));
int *tmp = malloc(4 * sizeof(int));
you declared two pointers list and tmp that has automatic storage duration. The pointers themselves point to dynamically allocated arrays that (the memory occupied by the arrays) should be freed using the function free to avoid memory leaks.
After calling the function free the pointers will have invalid values.
What the program is doing is at first it allocated dynamically an integer array with three elements and the address of the allocated memory is assigned to the pointer list.
int *list = malloc(3 *sizeof(int));
Then the program tries to reallocate the array by means at first of allocating dynamically a new array with four elements
int *tmp = malloc(4 * sizeof(int));
If the allocation was successful then the old array is freed
free(list);
and the address of the new array is assigned again to the pointer list.
list = tmp;
That is now the two pointers list and tmp point to the same dynamically allocated array. You can use either pointer to free the allocated memory but logically it is better to use the pointer list because the program simulates reallocation an array initially pointed to by the pointer list.

a bug in malloc which used to copy array elements

This code is meant to copy an int array with count elements to a newly applied memory area in the heap.
int copy(int *array ,int count){
int i;
int *myarray = (int*)malloc(count*sizeof(int));
if (myarray == NULL)
return -1;
for(int i = 0;i<count;i++)
{
myarray[i]=array[i];
}
return count;
i think maybe it forgets to use free() after using the malloc() function to free the memory but this code is meant to copy array element in the memory.so whether i am right ? If no, what is the really bug?
This function leaks memory.
myarray contains a pointer to allocated memory which contains a copy of the data in array. However, this pointer is not used in any way when the function returns so the pointer to the allocated memory is lost.
The function should return a pointer to this memory so that it can be used.
int *copy(int *array ,int count){
int i;
int *myarray = malloc(count*sizeof(int));
if (myarray == NULL)
return -1;
for(int i = 0;i<count;i++)
{
myarray[i]=array[i];
}
return myarray;
}
Note that it will be the responsibility of the calling function to free the memory when it is done with it.
Your copy function functions allocates memory and then copies the elements of the array to that newly allocated memory. So far so good, but then you simply throw away the pointer to that newly allocated memory.
It's like copying a letter by hand, putting the copy into a safe, closing the safe with the key and then throw the key away. Now the copy of the letter is in the safe, but you can't access it any more.
You probably want something like this:
...
int *copy(int *array, int count) // return a pointer to int, not an int
{
int *myarray = malloc(count*sizeof(int)); // (int*) cast is not needed
if (myarray == NULL)
return NULL; // return NULL if malloc fails
for(int i = 0; i < count; i++)
{
myarray[i] = array[i];
}
return myarray; // return pointer to newly allocated memory
}
...
int source[] = {1,2,3,4,5};
int *destination = copy(source, 5);
if (destination == NULL)
{
// handle error
}
// now destination points the the copy of the array
for (int i = 0; i < 5; i++)
{
printf("%d\n", destination[i]);
}
...
free(destination); // free allocated memory when you're done with it
...

How to free() the memory which is referenced by **pointer?

Please help me understand this:
I have a pointer to a pointer
char** word_array = NULL;
Then I dynamically allocate memory in my code:
n = 6;
word_array = (char *) malloc(n* sizeof(char*));
How do I delete all the memory allocated for the "array" of pointers? Is this call to free right?
free(word_array);
Or should I make a loop:
for(int i = 0 ; i < n; i++) free(word_array + i);
You used one malloc, so you should use one free.
Also the cast to char* is nonsense: word_array has type char**, not char*, and casting result of malloc() is discouraged.
So the entire flow will be like this:
int n;
char** word_array = NULL;
n = 6;
word_array = malloc(n* sizeof(char*));
if (word_array == NULL) {
/* handle allocation error */
} else {
/* do some work with word_array */
/* free pointers stored in word_array if they are dynamically allocated
and not freed yet */
free(word_array);
}

HEAP CORRUPTION DETECTED memory leak in C

I got and error which says
Debug assertation failed and heat corruption detected
like everything is working good in my program but I get that error. Where is the memory leak here? I have to free that memory in the main because my functions need to return pointers.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *dynamic_reader(unsigned int n) {
/*making new array and checking if allocation succeeded*/
int *mem;
mem = malloc(n * sizeof(int));
if (!mem) {
printf("Memory allocation failed\n");
exit(-1);
}
/*letting the user to input the values for the array*/
int i = 0;
while (i < n) {
scanf("\n%d", &mem[i]);
i++;
}
/*printing the array just to make sure everything is good*/
for (int j = 0; j < n; j++) {
printf("%d ", mem[j]);
}
return mem;
}
int *insert_into_array(int *arr, unsigned int num, int newval) {
/*making new bigger array*/
int *newarr = realloc(arr, (num + 1) * sizeof(int));
/*adding the integer to this new array */
newarr[num] = newval;
printf("\n");
/*printing to make sure everything is correct*/
for (int j = 0; j < num + 1; j++) {
printf("%d ", newarr[j]);
}
return newarr;
}
int main(void) {
/*In dynamic_reader function I need to make an array which size is given as a parameter*/
/*In this case I choosed 3*/
int *arr = dynamic_reader(3);
int num = 3;
/*In insert_into_array function I need to add one integer to this array I made in dynamic_reader*/
/*The parameters are the array, the number of elements in the array already done and the integer I want to add*/
int *c = insert_into_array(arr, num, 9);
/*I free the memory here because I need to return the pointers of these arrays in the function so it cant be done there*/
free(arr);
free(c);
}
You are double freeing your memory. Check the documentation for realloc. Realloc will either 1) expand the passed buffer or 2) will allocate a new buffer, copy the data, and free the original buffer. When you do:
free(arr);
free(c);
You are double freeing a value that was either once already freed by realloc or already freed by the first free(arr)
Additionally, you should check if realloc fails (returns NULL) and if so, handle the case appropriately.
First you malloc an array, which you return to your main function as arr. Then in another function, you realloc where arr is an argument to the realloc, but some other pointer stores the results. Depending on what happened in realloc, you've either got arr and newarr pointing to the same location, or newarr pointing to a valid location and arr pointing to an invalid location that has been freed. Either way, freeing both of them at the end is a problem.
No need to free(arr), that is taken care of when you realloc() it. The pointer returned by realloc() will either point to memory which includes the original memory, or free the old memory after copying its content to a new, larger chunk of memory.

Segmentation Fault when attempting to print value in C

The following C code returns a "segmentation fault" error. I do not understand why it does not return the value 20. What is my error?
#include <stdio.h>
int main()
{
int* n;
*n = 20;
printf("%i\n",*n);
return 0;
}
You haven't allocated memory to n, so
*n = 20;
attempts to write unspecified memory.
Try
#include <stdlib.h>
int *n = malloc(sizeof *n);
/* use n */
free(n);
You haven't allocated space for your int, you've only declared a pointer to an int.
The pointer is uninitialized, and so writing to that unknown space in memory is undefined behavior and causes problems. This typically causes a segfault.
You can allocate a slot for an integer using malloc:
n = malloc(sizeof(int));
And use a corresponding call to free to free up the memory later:
free(n);
But allocating a single slot for an integer is pretty unusual, typically you would allocate the int on the stack:
int n;
n = 20;
You are trying to write 20 in garbage value. You must allocate space for it by using one of *alloc() functions or creating an int on stack and getting the andress of it(as Richard J. Ross III mentioned on comments).
dynamic allocation:
int n*;
n = malloc(sizeof(int)); /* allocate space for an int */
if(n != NULL) {
/* do something.. */
free(n); /* free 'n' */
} else {
/*No space available. */
}
or on the stack:
int int_on_stack;
int *n = &int_on_stack;
*n = 20;
printf("%i\n", *n); // 20

Resources