This question already has answers here:
Changing address contained by pointer using function
(5 answers)
Closed last year.
# include<stdio.h>
# include<stdlib.h>
void fun(int *a)
{
a = (int*)malloc(sizeof(int));
}
int main(void)
{
int *p;
fun(p);
*p = 6;
printf("%d\n",*p);
free(p);
return(0);
}
In vs code this shows error because int *p is uninitialized and tells me to initialize the variable 'p' to NULL to silence this warning. But when I did that it compiled but showed segmentation fault, likely because I'm assigning 6 to the null address, so how do I fix this?
This function
void fun(int *a)
{
a = (int*)malloc(sizeof(int));
}
changes its own local variable (parameter) a. That is the function deals with a copy of the value of the passed pointer p
int *p;
fun(p);
The pointer p stays unchanged and uninitialized.
To make the program correct you need to change the code the following way
void fun(int **a)
{
*a = (int*)malloc(sizeof(int));
}
//...
int *p;
fun( &p);
Though in this case it would be better to declare and define the function like
int * fun( void )
{
return malloc(sizeof(int));
}
//...
int *p = fun();
if ( p )
{
*p = 6;
printf("%d\n",*p);
}
free(p);
Related
void func(char *p)
{
int q = 13;
p = &q;
printf("%d\n", *p);
}
void main(void)
{
int var = 20;
int *p = &var;
printf("%d\n", *p);
func(p);
printf("%d\n", *p);
}
How come at the function exit the pointer is still 20?
I was hopping when the func() ends, the pointer is modified in it, in the last printf(), the *p value would be pointing some random stuff from the stack.
What you had is this
void func(char *p)
{
int q = 13;
p = &q;
}
This means "make p point to q" and changes value of p, which is just a variable inside the function. No variable value changes are reflected outside the function.
If you were to write this
void func(char *p)
{
int q = 13;
*p = q;
}
This would mean "make the variable to which p points to change its value to 13" and that would be seen outside, meaning the variable var in main would change its value (depends on endianness what it would be since it's int and not char as the pointer claims it to be).
If you want to change the pointer's value in main you need a double pointer:
void func(char **p)
{
int q = 13;
*p = &q;
printf("%d\n", *p);
}
This would mean "make the pointer to which p points to point to a local variable q" and in this case you would have a dangling pointer as you expected in main.
No, p itself is passed be value. Any change made to p inside func() will not be reflected back to main().
For sake of completeness, any changes made to the value pointed to by p (i.e., *p) would have been reflected back in main().
This question already has answers here:
How to access a local variable from a different function using pointers?
(10 answers)
Closed 6 years ago.
I started studying pointers and I got in some trouble with the next code:
#include <stdio.h>
int * g()
{
int a = 10;
return &a;
}
void main()
{
int *p;
p=g();
printf("%d",*p);
}
It returns the error segmentation fault. core dumped
I would really apreciate any help. Have a nice day!
You are returning the address of a local variable. When you leave the function your code does not know this variable anymore, thus the segmentation fault.
You would have to give a pointer to this function as a parameter or dynamically create memory for this variable in the heap.
e.g.
void g(int* p) {
*p = 10;
}
int main() {
int a;
g(&a);
printf("%d", a);
return 0;
}
or
int* g() {
int* p = (int*) malloc(sizeof(int));
*p = 10;
return p;
}
int main() {
int* p;
p = g();
printf("%d", *p);
free(p)
return 0;
}
I know the c always pass by values, but if I have a pointer:
int i = 4;
int * p;
p = &i;
then I have a function, how to pass pointer p to it and change the value of variable i?
void changeValue(int *p)
{
}
how to pass the pointer and change the variable pointed by p?
This simple example shows how to pass a pointer (i.e. not a value) and recieve back through that pointer, the new value held by the integer. Note the reduced number of variables. i.e. there is no need necessarily to create a separate copy of int *p;. Nor is it necessary in this case to initialize p: p = &i; to the address of i.
int changeValue(int *);
int main(void)
{
int i=15;
changeValue(&i);
return 0;
}
int changeValue(int *p) //prototyped to accept int *
{
return *p = 3;
}
If you do want to create a pointer in the first place, and pass that pointer, then:
int changeValue(int *);
int main(void)
{
int i=15;
int *p;
p = &i;
*p; // *p == 15 at this point
//since p is already a pointer, just pass
//it as is
changeValue(p);
return 0;
}
int changeValue(int *q) //prototyped to accept int *
{
return *q = 3;
}
It is important to note that your statement: I know the c always pass by values is not correct. It is more common for functions to be written such that pointers are passed because often a pointer is smaller, and more efficient to pass around than the actual variable, especially when large arrays, or structs are used. Keep in mind though that passing &i (the address of i) works just as well as passing p if passing a pointer is called for.
Simply pass it by calling changeValue as
changeValue(p);
and change the value of variable pointed by it (i) by assigning a value to the *p in changeValue()
void changeValue(int *p)
{
*p = an int value;
}
void changeValue( int* ) ;
int main( void )
{
int i = 4; // Suppose i is stored at address 1000h
int * p;
p = &i; // Now p stores the address of i that is 1000h
changeValue(p); // Can also be written as changeValue(&i);
// Here you are passing the address of i to changeValue function
return 0 ;
}
void changeValue( int* p ) // Accept a parameter of type int*
{
*p = 100 ; // store the value 100 at address 1000h
return ;
}
int i = 4;
int * p = &i;
changeValue(p);
printf("%d",*p);
void changeValue(int *p)
{
*p = 5;
}
Full program - http://ideone.com/DCvhxE
If you dereference the pointer in changeValue and assign to it, it will alter the value of i in the calling frame.
e.g.:
void changeValue(int *p)
{
*p = 0;
}
This is in reference to this question: Why is a pointer to pointer needed to allocate memory in this function?
The answer to the question explained why this didn't work:
void three(int * p)
{
p = (int *) malloc(sizeof(int));
*p = 3;
}
void main()
{
int *p = 0;
three(p);
printf("%d", *p);
}
... but this works:
void three(int ** p)
{
*p = (int *) malloc(sizeof(int));
**p = 3;
}
void main()
{
int *p = 0;
three(&p);
printf("%d", *p);
}
This also works, by returning a pointer from the function. Why is that?
int* three(int * p)
{
p = (int *) malloc(sizeof(int));
*p = 3;
return p;
}
void main()
{
int *p = 0;
p = three(p);
printf("%d", *p);
}
int* three(int * p)
{
p = (int *) malloc(sizeof(int));
*p=3;
return p;
}
Because here you're returning a copy of the pointer p and this pointer now points to valid memory, which contains the value 3.
You originally passed in a copy of your p as an argument, so you're not changing the one you passed in, but a copy. Then you return that copy, and assign it.
From the comment, which is a very valid point, this will also work just as well:
int* three()
{
//no need to pass anything in. Just return it.
int * p = (int *) malloc(sizeof(int));
*p=3;
return p;
}
They're completely different (and if you truly understand why the first works, you'd see there's no connection).
By returning, you're not attempting to modify the already existing pointer from inside the function. You're just returning a new pointer, and assigning its value outside.
Look at it as a question of scope.
In main() you have a pointer p.
int *p = 0;
p in main is set to NULL. When you make a call to the three function passing it p:
three(p);
You are passing a pointer to NULL. What happens to it is outside the scope of main(). main() does not know, nor does it care what happens. main() only cares about its copy of p, which at this point is still set to NULL.
Unless I reassign p within the scope of main() (including handing off the address of p), p is still just a pointer pointing to NULL.
If I give you this code:
void main()
{
int *p = 0;
funcX(p);
printf("%d",*p);
}
You can tell me definitively what is going to happen (Segmentation fault) without ever knowing what funcX() does because we're passing a copy of the pointer to this function, but a copy doesn't affect the original.
But if I give you this code:
void main()
{
int *p = 0;
funcX(&p);
printf("%d",*p);
}
You can't tell me what will happen unless you know what funcX() is doing.
That make sense?
This question already has answers here:
C Programming: malloc() inside another function
(9 answers)
Closed 5 years ago.
I would like to know the technical reason(in terms of memory) why this piece of code will not work:
#include <stdio.h>
#include <stdlib.h>
int* fun(int*);
int main()
{
int a=5;
int* ptr;
// ptr=(int*)malloc(sizeof(int));
fun(ptr);
a=*ptr;
printf("\n the val of a is:%d",a);
return 0;
}
void fun(int* ptr)
{
ptr = (int*)malloc(sizeof(int));
*ptr = 115;
}
Why will this not work? I thought that the heap(more importantly the addresses) is common to all the function's variables in the stack .
Also, why would this work.
If i comment the memory allocation inside the function fun and uncomment the one in main . It works fine.
In C, everything is passed by value.
What you are passing to fun() is a copy of the pointer you have in main().
That means the copy of ptr is aimed at the allocated memory, and that memory set to 115.
The ptr in main() still points at an undefined location because it has never been assigned.
Try passing a pointer to the pointer, so that within fun() you have access to the pointer itself:
#include <stdio.h>
#include <stdlib.h>
int* fun(int**); // <<-- CHANGE
int main()
{
int a=5;
int* ptr;
// ptr=(int*)malloc(sizeof(int));
fun(&ptr); // <<-- CHANGE
a=*ptr;
printf("\n the val of a is:%d",a);
return 0;
}
int* fun(int** another_ptr) // <<-- CHANGE
{
*another_ptr = (int*)malloc(sizeof(int)); // <<-- CHANGE
**another_ptr = 115; // <<-- CHANGE
return *another_ptr;
}
The other option would be to make fun() actually return the updated pointer (as advertised), and assign this to ptr:
#include <stdio.h>
#include <stdlib.h>
int* fun(int*);
int main()
{
int a=5;
int* ptr;
// ptr=(int*)malloc(sizeof(int));
ptr = fun(ptr); // <<-- CHANGE
a=*ptr;
printf("\n the val of a is:%d",a);
return 0;
}
int* fun(int* another_ptr)
{
another_ptr = (int*)malloc(sizeof(int));
*another_ptr = 115;
return another_ptr; // <<-- CHANGE
}
Edit: I renamed the variable in fun() to make it clear that it is different from the one you use in main(). Same name doesn't mean anything here.
The fun() function parameter is a copy of the variable you passed into fun(). So when you do:
ptr = (int*)malloc(sizeof(int));
*ptr = 115;
you only change that copy. You should change the function signature:
int* fun(int** ptr)
{
*ptr = (int*)malloc(sizeof(int));
**ptr = 115;
}
and change how you call it accordingly.
You are confused about several things here, but one easy way of writing the function is:
int * fun()
{
int * ptr = (int*)malloc(sizeof(int));
* ptr = 115;
return ptr;
}
You are now responsible for freeing the memory, so in main():
int * ip = fun();
printf( "%d", * ip );
free( ip );
The alternative is to pass the address of apointer (a pointer to a pointer) to the function:
void fun( int ** pp )
{
* pp = (int*)malloc(sizeof(int));
** pp = 115;
}
then your code in main() looks like:
int * ip;
fun( & ip );
printf( "%d", * ip );
free( ip );
I think you can see that the first function is simpler to use.
You need to pass the address of the pointer in main if you want to change it:
fun(&ptr);
(and change fun appropriately, of course)
At the moment, it's changing the local variable ptr inside the function, and of course that change doesn't magically appear anywhere else.
You're passing the ptr by value to fun. fun will recieve a copy of ptr which will be modified. You need to pass ptr as int**.
void fun(int** ptr)
{
*ptr = (int*)malloc(sizeof(int));
**ptr = 115;
}
and call it with:
fun(&ptr);
(I also removed the return value from fun since it wasn't used)
The variable int* ptr is passed by value to the function fun. So the value assigned to ptr inside the function using ptr = (int*)malloc(sizeof(int)); will not be reflected outside the function. So when you do a = *ptr; in main() you are trying to use an un-initialized pointer. If you want to to reflect the changes done to ptr outside the function then you need to change the signature of fun to fun(int** ptr) and do *ptr = (int*)malloc(sizeof(int));
Remember that if you want a function to modify the value of an argument, you must pass a pointer to that argument. This applies to pointer values; if you want a function to modify a pointer value (not what the pointer points to), you must pass a pointer to that pointer:
void fun (int **ptr)
{
/**
* Do not cast the result of malloc() unless you are
* working with a *very* old compiler (pre-C89).
* Doing so will supress a valuable warning if you
* forget to include stdlib.h or otherwise don't have
* a prototype for malloc in scope.
*
* Also, use the sizeof operator on the item you're
* allocating, rather than a type expression; if you
* change the base type of ptr (say from int to long),
* then you don't have to change all the corresponding
* malloc() calls as well.
*
* type of ptr = int **
* type of *ptr = int *
* type of **ptr = int
*/
*ptr = malloc(sizeof **ptr);
*ptr = 115;
}
int main(void)
{
int *p;
fun(&p);
printf("Integer value stored at %p is %d\n", (void *) p, *p);
return 0;
}
BTW, you have a type mismatch in your example; your initial declaration of fun returns an int *, but the definition returns void.