When a function returns, is the memory allocated via malloc freed? Or can it still be accessed in the main() function using pointers?
eg.
void function(int *a)
{
a=(int *)malloc(sizeof(int));
*a=10;
}
int main()
{
int *num;
function(num);
printf("%d",*num);
return(0);
}
Can the integer stored in a be accessed by main() here?
No, the memory allocated with malloc is not freed when you leave the scope/return from the function.
You're responsible for freeing the memory you malloc.
In your case though, the memory is NOT accesible in main(), but that's because you only deal with a local variable.
void function(int *a)
{
a=(int *)malloc(sizeof(int));
Here, a is a local variable within function . Pointers are passed by value in C, so a receives a copy of the pointer in main when you do function(num); main() does not see that you assign to that local copy of the pointer.
You have to do either:
void function(int **a)
{
*a= malloc(sizeof(int));
**a=10;
}
int main()
{
int *num;
function(&num);
printf("%d",*num);
free(num);
return(0);
}
or
int* function(void)
{
int *a= malloc(sizeof(int));
*a=10;
return a;
}
int main()
{
int *num;
num = function();
printf("%d",*num);
free(num);
return(0);
}
malloc()ed memory is only freed when you call free() on it. It can be accessed by anybody with a valid pointer to it until that time.
No. You are passing the pointer numby value, hence the changes made by the function will not be reflected in main. So effectively there is no way to access/free the allocated memory from main
To fix this you can pass the address of num or return a from function and collect the returned value in num
Memory is not freed. Any function can allocate memory and any other can deallocate it. It's a real mess if you're not super-finicky, until... someone invented the Garbage Collection.
malloc is working fine (though you will have to call free() on the pointer it returns). The problem here is that you aren't returning a pointer to the memory it allocated.
"int * a", your parameter to function() is the address of an integer. The usual way to return that would be to rewrite your function as follows:
int * function()
{
int * a = (int *)malloc(sizeof(int));
*a = 10;
return a;
}
To return it via a parameter, you need to return the address of the pointer:
// pp points to a pointer
void function( int ** pp )
{
// Assign allocated memory to the thing that pp points to
*pp = (int *)malloc( sizeof( int ) );
// Get the thing pp points to -- a pointer.
// Then get the thing which THAT pointer points to -- an integer
// Assign 10 to that integer.
**pp = 10;
}
void main()
{
int * p = NULL;
function( & p );
printf( "%d\n", *p );
free( p );
}
And now you know why they invented C#.
Here's a way to rewrite your allocation thing so it's more clear:
void function( int ** pp )
{
int * newmemory = (int *)malloc( sizeof( int ) );
// Assign 10 to the integer-sized piece of memory we just allocated.
*newmemory = 10;
// Assign allocated memory to the thing that pp points to.
*pp = newmemory;
}
You can store the direct address of the allocated memory in a list container then create a function to loop, access each address into a free function, and then pop out the address. You can insert the address directly into the free function like free(myaddresslist.front()); myaddresslist.pop_front(); . This is a quasi way of doing your own garbage collection without having to change your entire project to GC based languages. Use myaddresslist.size() to make sure you don't call free() on an empty field (resulting in a crash) and to determine the number of loops to take.
Related
The question is to receive a new number and sort all in descending order.I want to combine old with new number ,put them to a new array.and then sort them.I took a long time to handle with it but failed.SOS! What is the problem?😑
int* fun(int* a, int num){
int pa[7];
for(int i=0;i<5;i++){
pa[i]=a[i];
}
pa[6]=num;
swap(pa,7);
return pa;
}
void swap(int *pa,int n)
{
int i,j,t;
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(*(pa+i)>*(pa+j))
{
t=*(pa+i);
*(pa+i)=*(pa+j);
*(pa+j)=t;
}
}
}
}
int main(){
int a[7]={86,89,23,34,11,87};
int num;
scanf("%d",&num);
int *pa=fun(a,num);
for(int i=0;i<7;i++)
printf("%d ",*(pa+i));
return 0;
}
The pa in your fun() is a local variable to it. This means that anything concerned with pa is freed when your function returns. If you want to return a newly formed array, use dynamic memory allocation with the aid of malloc() or calloc() functions and not simply an array you create and pass a reference of.
Sometimes, you may get the contents you expect from such a return, but it is not certain as the memory you are returning is now free to be reused and can be overwritten. The contents of the pa in fun() after returning are not guaranteed.
Function variables are created in the stack. After the execution of the function ends, all of its variables are "removed" from stack. So you can't access them outside the function. For example,
int* f(){
int x = 5;
int* a = &x;
return a;
}
This function will return the address of x but that address will be an invalid address because the variables x, a cease to exist after the execution of the function ends.
How to get around it?
Store the data in the heap. The stack is cleared after the execution of the function ends but heap is not cleared, so you can store something in the heap and access it later from anywhere anytime.
int* fun(){
int*x = (int*)malloc(sizeof(int)); // allocates 4 byte memory in the heap.
*x=5;
return x;
}
int main(){
int* check = fun();
printf("Value: %d\n",*check);
}
I simply want to assign a pointer to another pointer via the function (same memory address). My code is below:
#include <stdio.h>
void d(int** a)
{
int* val_ptr = malloc(1);
*val_ptr = 5;
printf("%d\n", *val_ptr);
a = &val_ptr;
}
int main()
{
int* a = NULL;
d(&a);
printf("%d\n", *a);
return 0;
}
Output from Link
5
Segmentation fault
Your code has three problems:
Here int* val_ptr = malloc(1);, you allocate 1 byte rather than allocating space for an int. Use the following to fix it:
int* val_ptr = malloc(1 * sizeof(int));
This a = &val_ptr; is not what you want. It changes the local pointer and makes it point to the address of val_ptr. This will not affect the pointer that you've defined in main.
Fix it using
*a = val_ptr;
This way, the pointer in main will also reflect the change and will point to the malloced memory
You should free the allocated memory after its use. Add
free(a);
after the printf in main to free it.
#include <stdio.h>
#include <stdlib.h>
int* func();
int main(void) {
int *b = NULL,i;
b = func();
for(i=0;i<7;i++)
{
printf("%d\n",*b);
b++;
}
}
int * func()
{
int *p;
p = malloc(sizeof(int) * 7);
int arr[]={1,2,3,4,5,6,7}; //without using static
p = arr;
return p;
}
How to return the address of the array to the main function for printing the values ?? Without declaring the array as static if we allocate memory for the array in heap then can we able to pass the array to the function as a pointer ??
You are close, but not quite there.
The following expressing causes p to point to arr's address which is not the intended effect:
p = arr;
Remember, p is a pointer, and if you do not use the dereference operator *, then you are refering to the pointer's address rather than its value. arr's memory is deallocated when the function exits, and the memory malloc'd to p is lost because you reassigned the address of p to point to the address of the local variable arr.
The solution is to copy the values of arr to p using a for loop:
int i = 0;
for (; i < 7; ++i) {
p[i] = arr[i];
}
This will print the desired result because you replaced the values of what p pointed to rather than the address of p itself.
You can't. The array is gone when you leave the function, any pointer to the array would have an undeterminate value when you leave the function, and using such a pointer in any way invokes undefined behaviour.
Your malloc () call is pointless and leads to a memory leak, because you allocate space for 7 ints on the heap, and then overwrite the pointer, so the memory can never be used or freed.
I'm interested the difference between these two scenarios:
int *function() {
int i = 5;
return &i;
}
and
int *function() {
int *i = calloc(1, sizeof(int));
*i = 5;
return i;
}
is there a difference? If so, can someone explain what is going on in the background?
Yes there is a difference. In the first scenario, the integer i is being allocated on the stack, which means it will get reused when the function returns. In the second scenario, the memory is being allocated on the heap and will not get overwritten outside of the function call.
what's happening after clrscr?
#include<stdio.h>
#include<conio.h>
int *call();
void main()
{
int *ptr;
ptr=call();
clrscr();
printf("%d",*ptr);
getch();
}
int*call()
{
int a=25;
a++;
return &a;
}
output:
-10
code works like this:
call() is called, a=25, then a=26. let address of a be 65518. this address is returned to ptr. since return type is int, instead of 65518, (due to cyclic property) -18 is returned.
so ptr=&a=-18. then clrscr clears it....but how *ptr is printed as output? i mean address cannot be negative(-18).
Returning a pointer to local is undefined behavior. Anything could happen - your program could crash, but more likely it is going to print some arbitrary number.
If you need to return a pointer from a C function, you need to either allocate a memory block in the dynamic storage, like this:
int*call()
{
int *a=malloc(sizeof(int));
*a = 25;
*a++;
return a;
}
or use a pointer to a statically allocated block, like this:
int* call()
{
static int a=25;
a++;
return &a;
}
If you choose the dynamic allocation route, the caller must free the pointer returned by your function.
int*call()
{
int a=25; // <--- use malloc here i.e. int a = malloc(sizeof(int)); then you can set a value to a and return the pointer without any problemk, OTHERWISE => it will return an address of some random junks you don't want, its gonna be completely random
a++;
return &a;
}
When call() is called, a new stack frame is created with space for the local variable a, which has its lifetime during the execution of call(). When it returns, the stack frame is removed along with its local variable(s) and data. Trying to use this data outside the function is undefined, because it no longer exists, logically.
If you want to declare a inside a function and use it afterwards, you'll need to allocate it:
...
int *a = malloc(sizeof int);
*a = 26;
return a;
...
Remember to free() this pointer after you're finished using it.