glibc detected free() invalid pointer - c

I'm having a bit of trouble with some dynamic memory allocation.
Below is just a test code that I've been playing around with to try and fix the problem (it's the same problem in my current project's code, this is just a simpler way to show it).
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
int main(){
int x = 5;
int *ptr = (int*) malloc(sizeof(int));
assert(ptr != NULL);
ptr = &x;
printf("x = %d\n",x);
*ptr = 3;
printf("x = %d\n",x);
free(ptr);
return 0;
}
The program compiles fine and when run I get the correct outputs printed "x = 5 x = 3"
But then I get the error:
glibc detected ./dnam: free(): invalid pointer: 0xbfccf698
dnam is the name of the test program.
From what I've read about the error, it's supposedly caused by freeing memory that you haven't malloc/calloc/realloc'd.
This error message is followed by a backtrace and a memory map. AT the end of the memory map I'm told the program has aborted (core dumped).

int *ptr = (int*) malloc(sizeof(int));
ptr = &x;
You are changing ptr value! The compiler will be taking unlimited revenge if you attempt to free it.
Here:
free(ptr);
You are free-ing an object not allocated through malloc.

You are allocating memory and saving its address into ptr. Then, you make ptr point to x's address, thus when you run free(ptr) you essentially freeing &x, which doesn't work.
tl;dr: there's no need for malloc and free when you're assigning the pointer a pointer to another var.

if you want use this code.I think you should use a temp pointer save the init ptr.at last free(temp).like this:
int *temp = ptr;
free(temp);

Related

Free uninitiailized pointer in C

If I dynamically allocated a space for a pointer, list this:
int *a = (int*)malloc(sizeof(int));
should I free a when the code is done? Thanks!
I think you have a little misunderstanding related to pointer.
Your title says:
Free uninitialized pointer ...
and your code is
int *a = (int*)malloc(sizeof(int));
The problem with this is that there is no uninitialized pointer in the code. The only pointer in the code is the variable a and it is initialized by the value returned by malloc.
Freeing an uninitialized pointer would be bad - example:
int *a; // a is an uninitialized pointer
free(a); // Real bad - don't do this
but since you actually initialize the pointer then - Yes, you must call free when your are done using the object/memory pointer a points to. It does not matter whether or not the pointed-to object (aka memory) has been assigned a value.
The general rule: For each call of malloc there must be a call of free
(Exception: If your program terminates, you don't need to call free)
int *a = malloc(sizeof(*a));
if (a)
{
/* a is now valid; use it: */
*a = 1 + 2 + 3;
printf("The value calculated is %d\n", *a);
}
/* Variable A is done being used; free the memory. */
free(a); /* If a failed to be allocated, it is NULL, and this call is safe. */
Yes.
If you successfully malloc something is is correct to free it as well.
int *a = (int *) malloc(sizeof int);
if (a != NULL)
{
/* Do whatever you need to do with a */
free(a);
}
else
{
puts("the malloc function failed to allocate an int");
}
int *a = (int*)malloc(sizeof(int));
should I free a when the code is done?
The question should be
Must I free a when the code is done?
And the answer is YES. A malloc must be accompanied by a a free statement.
free(a);

Segmentation fault after realloc in function

I have created this code to test one error, that I get in my main code, and it shares the same problem. I'm always getting either segmentation fault or corrupted data (zeros or strange numbers).
Here is the code:
int *p=NULL;
int func (int **point);
int main() {
int num = 5647;
p = malloc(sizeof(int)*2);
p[0] = num;
p[1]= 657;
printf("%d\n", p[0]);
printf("%d\n", p[1]);
func(&p);
printf("%d\n", p[0]);
printf("%d\n", p[1]);
printf("%d\n", p[2]);
printf("%d\n", p[3]);
return 0;
}
int func (int **point){
*point = realloc(*point,sizeof(int)*4);
if (*point==NULL){
printf("\n abort \n");
exit(0);
}
*point[0] = 867;
*point[1]= 777;
*point[2] = 67;
*point[3]= 77;
}
I'm getting the segmentation fault on the *point[1]=777;. If I'm trying to do like point[1]=777; I'm getting wrong data. With any changes in int func (int **point); or func(&p); I'm getting segmentation fault on realloc.
Please advise, I have read information about double pointers and tried to follow all solutions I found, but every time I'm getting this error.
Your problem is operator precedence, change *point[0] to (*point)[0] and so forth.
What you have right now is *(point[0]). You treat a pointer to a single element as a pointer to multiple consecutive elements and then dereference some indeterminate value as an address. This results in undefined behavior, which luckily for you manifests as a crash.
After the change you first dereference point and then use that address to index into consecutive elements you allocated.
Two suggestions for improvement:
Don't assign the result of realloc directly to *point. If the call fails, then you leak the original memory. Assign it to a temporary first for verification.
Also, try not to repeat types. Instead of sizeof(int) try for sizeof(**point), i.e whatever the output buffer is supposed to point at. That way you won't have silent errors in your code if you change the type from int to something else.
void *point_check = realloc(*point,sizeof(**point)*4);
if (point_check == NULL){
printf("\n abort \n");
exit(0); // If this ever returns instead of exit, `*point` will not leak
}
*point = point_check;

Can we free dynamically allocation memory using realloc?

My friend and I had a discussion over freeing dynamically allocated memory. He told that a memory could be freed with realloc(), to which I denied.
Let's consider the below code:
int main()
{
int *p = (int *)malloc(sizeof(int) * 10);
int *q = (int *)malloc(sizeof(int) * 10);
free(p);
p = NULL;
realloc(q, sizeof(int) * 0);
q = NULL;
_getch();
return 0;
}
Let's assume p and q are pointing to address 0x1000 & 0x2000 respectively.
In the above code, p and q are int pointers pointing to dynamically allocated 40 bytes of memory blocks in the RAM. On executing free(p) frees the memory address (0x1000). The freed memory address (0x1000) could be used by an OS again. Then, NULL is assigned to pointer variable p to prevent p of becoming a dangling pointer.
realloc(q, sizeof(int) * 0);
realloc() simply shrinks the memory block pointed by q to zero. But q still points to the same address (0x2000), and that address is not freed. On assigning NULL value to pointer q, q now points to NULL and the address (0x2000) to which q was pointing is not freed and the link to that address (0x2000) is lost. That address (0x2000) cannot be used by OS in the future until the end of the program.
Is my understanding correct?
realloc(, 0) is implementation dependent and not equivalent to free().
That said, you might be lucky:
#include <stdio.h>
#include <malloc.h>
int main() {
char *a;
a = malloc(1024);
printf("a = %08lx\n", a);
free(a);
a = malloc(1024);
printf("a = %08lx\n", a);
realloc(a, 0);
a = malloc(1024);
printf("a = %08lx\n", a);
}
gcc version 6.1.1 20160815 [gcc-6-branch revision 239479] (SUSE Linux)
ldd --version
ldd (GNU libc) 2.23
a = 01dad010
a = 01dad010
a = 01dad010
So the second malloc, after realloc(, 0), "sees" a free block where before was a. I take it to mean that in this instance, realloc duplicates the behaviour of free. DO NOT RELY ON THIS.
realloc(q, sizeof(int) * 0);
is same as
realloc(q, 0);
The C standard in 7.22.3.5 ->2 The realloc function says :
..and returns a pointer to a new object that has the size specified by
size. The contents of the new object shall be the same as that of the
old object prior to deallocation, up to the lesser of the new and old
sizes.
But it doesn't explicitly specify what would happen if the new size is zero.
But you still have an artist pointer that could be passed to free.
Consider
char *a;
a=malloc(2*sizeof *a);
a=realloc(a,0);
// Note I'm purposely NOT using a temporary variable to store 'realloc' results
// Moreover, above is BAD practice.
free(a); // Is this permitted? YES !! Did we technically free memory above? NO !!
//Compiler will not yell at you for the above, in fact it is legal as per the standard
return 0; // No output for this one
vs
char *a;
a=malloc(2*sizeof *a);
free(a);
//You're not suppose to free(a) again.
free(a);
//Compiler will yell at you for the above.
return 0;
output
double free or corruption (fasttop): 0x0000000000915010
Conclusions
deallocation and freeing are not exactly the same things.
Both realloc and free can deallocate memory, but only free frees the memory.
That said
free(p);
p = NULL;
is the recommended way to free memory. Do check [ this ] answer.

How does int *p = 10; work?

I have a statement int *p = 10; . This statement executes perfectly fine on any compiler. I also know that 10 is put in read-only memory. Is there a way i can access this memory. How can I print this on console? The statement printf("%d",*p) crashes. How can I make it print on console.
Edit
int main()
{
int *p = 10;
}
the above code compiles fine and runs fine.
int main()
{
int *p = 10;
printf("\n%d",*p); //crashes
}
the above code gives segmentation fault. I wanted to know more explanation on this?
By typing int *p = 10; you say to compiler:
Lets have a pointer on integer, called "p".
Set p to 10 => p points on address 10 on memory.
By typing printf("%d",*p); you say to compiler:
Show me -as a integer- what is at the address 10 on memory.
The code
int *p = 10;
Is equivalent to:
int *p;
p = 10;
Is not equivalent to:
int *p;
*p = 10;
Corrected code could be:
// define an integer
int i;
// define a pointer on the integer
int *p = &i;
// set integer to 10, through pointer
*p = 10;
// display integer through pointer
printf("%d",*p);
I think my answer is great for you,you may misunderstand the definition of the pointer and use the pointer in a wrong way. Let`s analyse your code first:
int *p = 10
this statement defines a pointer which is pointed to address 10 in memory, it compiles OK because there's no syntax error--the content of p is the address 10, but you have no idea what's value in address 10, and it generally doesn't have a internal memory to store a value cuz you haven`t allocate the memory for it.it's also very dangerous that you are tring to use a system memory 10.
You can print the address which has been pointed by p:
printf("%d\n", p);//p is pointed to address 10
So when you tried to print the content of p by:
printf("\n%d",*p);
which haven't allocate the memory to store the content,segmentation fault occurs!
If u want to assign value for pointer directly u must dynamic application of memory space for it first, you should write in this way:
int *p = NULL;//the right and safe habit to define a pointer
p = (int *)malloc (sizeof(int));//dynamic application of memory space of pointer p to store value
if (NULL == p)
{
printf("malloc failed!\n");//show error
exit(1);//exit
}
*p = 10;//now you have memory space to store value 10
printf("%d\n", *p);
free(p);//release the memory to avoid memory leaks
p = NULL;//the right and safe habit
You can also write in this way:
int transfer_value = 10;//integer has memory when you declare it
int *p = &transfer_value;//p stores the address of i which content is value 10
printf("%d\n", *p);//because variable i has memory which size is sizeof(int), you can print *p(it stands for the value of i)directly.
Hope my explanation could help you ^_^
Segmentation fault is a error when there is a memory access violation. Dynamic memory allocation will solve your problem. Kernel will decide which memory address should be used to store the value.
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *p = malloc(sizeof(int)); //Kernel will assign a memory from Heap segment
*p=10;
printf("\n%d",*p);
free(p);
}
You have created a pointer, not a value. You probable want just int i=10. Otherwise, the program is accessing random memory at address 10 and will crash.
When you assign the value 10 to your pointer, you actually assign the address 10 to it. When you initialize you don't get any error, but when you try to print it you have to access it, and you don't have access to this memory address (that's why you have a segmentation fault).
If you do this :
int i = 10;
int *ptr = &i;
printf("%d\n", *ptr);
It will work because you make the pointer points to the variable i which contains the value 10.
int *p = 10;
creates a pointer p and sets it to point to the memory address 10, which is most likely not an accessible address on your platform, hence the crash in the printf statement.
A valid pointer is obtained by using the unary & operator on another object, such as
int i = 10;
int *p = &i;
or by calling a function that returns a pointer value such as malloc or fopen. Some platforms may expose specific addresses for particular operations, but those are usually well-documented and not such low address values.

Segmentation fault (core dumped) in c program

i am using gcc compiler on ubuntu 14.04 LTS for compilation of following c program
#include<stdio.h>
void main()
{
int *a,*b;
*a=2;
*b=3;
printf("\n printing address.....\n address of a = %d \n address of b = %d \n",a,b);
printf("\n\n printing values ..... \n value of a = %d \n value of b = %d \n",*a,*b);
}
and when i run above program than i get following in output
output: Segmentation fault (core dumped)
please suggest where i am doing wrong.
thanks
You're declaring and using pointers (pointed-to memory), without allocating space for them.
Just declaring:
int *a;
doesn't give you memory to use, this just declares a variable that can reference memory.
The pointer, once declared, is un-initialized, and will point to some part of memory that doesn't belong to you. Using that memory - in your case, putting a value there - will result in undefined behavior; you see a core dump when you touch that memory.
In order to get some space to use, learn about malloc:
int *a = NULL; // good practive to initialize/reset pointers to NULL
// malloc will give you space for 1 int, and a will point to that new space
a = malloc(sizeof(int));
if (a != NULL) // malloc returns NULL in the event of a failure
{
// a is non-NULL so now we can use the memory pointed-to:
*a = 5;
// other code that uses a goes here:
...
// and when you're finished with a give the memory back:
free(a);
a = NULL;
}
When you declare a pointer
int* p;
it is similar as declaring an integer variable:
int v;
the contents of v is uninitialized - same with p - it is also uninitialized so when you use p e.g. *p you may be dereferencing an address anywhere in memory, even in read-only memory. Instead you need to initialize the variables.
int v = 0;
int* p = &v; // p points to v in memory

Resources