Hi,
I'm a bit new to C's malloc function, but from what I know it should store the value in the heap, so you can reference it with a pointer from outside the original scope. I created a test program that is supposed to do this but I keep getting the value 0, after running the program. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
int f1(int *b) {
b = malloc(sizeof(int));
*b = 5;
}
int main(void) {
int *a;
f1(a);
printf("%d\n", a);
return 0;
}
Yes! a is passed by value so the pointer b in function f1 will be local..
either return b,
int *f1() {
int * b = malloc(sizeof(int));
*b = 5;
return b;
}
int main() {
int * a;
a = f1();
printf("%d\n", *a);
// keep it clean :
free(a);
return 0;
}
or pass a's address
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
int main() {
int * a;
f1(&a);
printf("%d\n", *a);
// keep it clean :
free(a);
return 0;
}
It looks like you're misunderstanding a fundamental part of how C works - namely that it is a 'pass-by-value' language. In order for main() to know about the memory you allocated, you have to get it back out. The following code will do you what you want:
int f1(int **b)
{
*b = malloc(sizeof(int));
**b = 5;
}
int main(int argc, char **argv)
{
int *a;
f1(&a);
printf("%d\n", *a);
return 0;
}
There are a couple differences between this code and yours; first, the signature of f1() has changed, so that it can return the result of the malloc() call in the passed in pointer. Next, the call to f1() has been changed to pass the address of a rather than a itself - important if you want it to be 'filled-in' by f1(), so to speak. Finally, the printf() in main() has been changed to print out the pointed-to value rather than the pointer itself.
The memory itself persists, but it leaks because you're not providing the allocated pointer to the caller. Also, you're printing a when you should be printing *a. Finally, you're not returning an int from f1.
Try:
void f1(int **b) {
*b = malloc(sizeof(int));
**b = 5;
}
int main() {
int *a;
f1(&a);
printf("%d\n", *a);
free(a);
return 0;
}
Lets suppose you assign a value of NULL to a before you call function f1. Now the way f1 is defined it takes its argument(pointer to an int) by value. That is b will be another variable of type int * which will be a copy of a. So b too will have a value of NULL. Now in f1 you change the value by b by assigning it the address of memory allocated dynamically using malloc. Lets say that memory address is 0x123. As a result of this assignment, b has changed its value from NULL to 0x123 but a(in main) continues to hold NULL, because changing b will not change a, as they are two separate variables. As a result of this when you return from function f1 a will remain unchanged.
There are 2 ways to solve this. One you can make the function f1 return the value of the changed b and then assign it back to a in main and two, you can pass the a by address so that any changes made in f1 will affect a in main too.
// f1 now returns the value of b.
int* f1() {
int *b = malloc(sizeof(int));
*b = 5;
return b;
}
int main() {
int *a = NULL;
a = f1(); // assign the return value of f1 to a.
printf("%d\n", *a); // prints 5...not its *a not just a.
return 0;
}
.
// f1 now takes the address of a.
void f1(int **b) {
*b = malloc(sizeof(int)); // you are actually altering a indirectly.
**b = 5;
}
int main() {
int *a = NULL;
f1(&a); // now pass the address of a to f1.
printf("%d\n", *a); // prints 5...not its *a not just a.
return 0;
}
The address int *b is deleted when the function return. To save it, you need to use a pointer of a pointer
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
Your problem is actually not related to malloc, but rather the fact that you're passing the value the pointer currently holds, rather than the address of it. Try the following:
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
int main() {
int * a;
f1(&a);
printf("%d\n", *a);
return 0;
}
By passing the pointer value as you were, there was no way for the value malloc created to be stored into the pointer.
Related
I am wondering that unlike the double pointers (int**) , can we have double function pointer?
I mean the function pointer pointing to the address of the another function pointer ?
I want something like
int add(int A , int B){
return A+B;
}
int main(void){
int (*funcpointerToAdd)(int,int) = add; // single function pointer pointing to the function add
printf("%d \n",funcpointerToAdd(2,3));
int (**doubleFuncPointerToAdd)(int,int) = &funcpointerToAdd;
printf("%d \n",doubleFuncPointerToAdd(2,3));
return 0;
}
but this gives me an error called object ‘doubleFuncPointerToAdd’ is not a function or function pointer
is this possible to do this thing anyway ?
You can use pointers to pointers to functions, but you have to deference them once first:
int add(int A , int B){
return A+B;
}
int main(void){
int (*funcpointerToAdd)(int,int) = &add;
//By the way, it is a POINTER to a function, so you need to add the ampersand
//to get its location in memory. In c++ it is implied for functions, but
//you should still use it.
printf("%d \n",funcpointerToAdd(2,3));
int (**doubleFuncPointerToAdd)(int,int) = &funcpointerToAdd;
printf("%d \n",(*doubleFuncPointerToAdd)(2,3));
//You need to dereference the double pointer,
//to turn it into a normal pointer, which you can then call
return 0;
}
This is also true for other types:
struct whatever {
int a;
};
int main() {
whatever s;
s.a = 15;
printf("%d\n",s.a);
whatever* p1 = &s;
printf("%d\n",p1->a); //OK
//x->y is just a shortcut for (*x).y
whatever** p2 = &p1;
printf("%d\n",p2->a); //ERROR, trying to get value (*p2).a,
//which is a double pointer, so it's equivalent to p1.a
printf("%d\n",(*p2)->a); //OK
}
int main ()
{
int a, b;
call(&b);
printf("%d, %d",a , b);
}
void call(int *ptr)
{
}
Desired output:
50, 100
How to write the call function so as to modify both the variables to get the desired output??
Not sure where the values 50 and 100 are coming from or exactly what you are asking but maybe this will help with your question.
Since C is pass by value you need to send pointers to actually change the value inside another function.
Since the call function will have pointer values you need to dereference the pointers before changing the value.
Here is an example:
void call(int *a, int *b)
{
*a = 50;
*b = 100;
}
int main()
{
int a, b;
call(&a, &b);
printf("%d, %d\n", a, b);
}
While we are exploring the many ways this output could be achieved, consider that the function could store state in a static variable:
#include <stdio.h>
void call(int *ptr);
int main(void)
{
int a, b;
call(&a);
call(&b);
printf("%d, %d\n",a , b);
}
void call(int *ptr)
{
static int store = 0;
store += 50;
*ptr = store;
}
Program output:
50, 100
Note that you may also be able to do this as follows, without any modifications to main(). But be warned that this method invokes undefined behavior! It is undefined behavior to write to a location past the end of an array object, and in the case of a and b, these are considered to be array objects of size 1. Here we are assuming that this write will work, and that a and b are stored next to each other in memory. We further assume that a has the higher address in memory.
I would say that you should never do this, but I can see no other way to modify a from the function call() without knowing the address of a. You have been warned.
void call(int *ptr)
{
*ptr = 100;
*(ptr + 1) = 50;
}
Try something like this:
void call(int *ptr)
{
*ptr = 100;
}
int main ()
{
int a, b;
a = 50;
call(&b);
printf("%d, %d",a , b);
}
See demo
Maybe you want this:
int main ()
{
int a, b;
call(&a, &b);
printf("%d, %d",a , b);
}
void call(int *ptr1, int *ptr2)
{
*a = 50;
*b = 100;
}
To change a local variable in function a by calling function b you have two options.
1) Let function b return a value that you assign to the variable in function a. Like:
int b() {return 42;}
void a()
{
int x = b();
printf("%d\n", x);
}
This does, however, not seem to be what you are looking for.
2) Pass a pointer to the variable to function b and change the variable through that pointer
void b(int* p) // Notice the * which means the function takes a pointer
// to integer as argument
{
*p = 42; // Notice the * which means that 42 is assigned to the variable
// that p points to
}
void a()
{
int x;
b(&x); // Notice the & which means "address of x" and thereby
// becomes a pointer to the integer x
printf("%d\n", x);
}
int main()
{
int a,b;
call(&b);
printf("%d, %d\n", a,b);
}
int call(int *ptr)
{
int *m;
m = ptr++;
*ptr = 50;
*m = 100;
}
This is the code here:
#include<stdio.h>
void assign (int *a1, int *a2) {
a1 = a2;
}
int main() {
int *a; int b; int *c; int d;
b = d = 5;
a = &b;
printf("%d", *a);
assign(c, &d);
printf("\n%d", *c);
return 0;
}
It's fine when I assign pointers manually in the main() function, but the segmentation fault appears when I assign it in the function. Why is this so?
The function assign has no effect. All it's doing is performing a local assignment which has no effect on the caller. As a result, c is undefined in main and you get a segmentation fault.
In order for assign to do what you intend, you have to pass it the address of c, then do a pointer assignment in assign.
Try the following:
#include <stdio.h>
void assign (int **a1, int *a2) {
*a1 = a2;
}
int main() {
int *a; int b; int *c; int d;
b = d = 5;
a = &b;
printf("%d\n", *a);
assign(&c, &d);
printf("%d\n", *c);
return 0;
}
The output is:
5
5
I also moved the newlines to the end of the format strings, which is the normal place to put them.
c is passed by value into the function assign. This means that modifying a1 from the function will not affect c.
To get the expected results, pass c by reference, i.e, pass the address of c:
assign(&c, &d);
and make slight modifications to the function:
void assign (int **a1, int *a2) {
*a1 = a2;
}
and you are good to go! :-)
Arguments are passed by value in C, so modyfying a1 in assign() won't affect c in main().
c remains uninitialized and it has automatic storage duration, so its value is indeterminate.
Then, you used this inderminate value in printf("\n%d", *c);.
This invokes undefined behavor and the program just happened to cause segmentation fault.
I am new to pointers.
For the below program , I get an answer of 255 and not 20. Please suggest how to correct.
Here is the code :
int sum(int *a , int *b);
int main()
{
int *p;
int *q;
*p =10;
*q =10;
int c = sum(p,q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}
There is data, then there are pointers. For simplicity, once you have data, then you can point to it. This is accomplished by using the & operator. To go back to the data from a pointer, use the * operator as you have
Something more like
int sum(int *a , int *b);
int main()
{
int p_data=10;
int q_data=10;
int *p =&p_data;
int *q =&q_data;
int c = sum(p,q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}
EDIT: Also note that pointers can be used to access memory allocated from malloc, or mmap'd, or other means
You need to alloc memory for pointers. This code should work:
#include <stdio.h>
#include <stdlib.h>
int sum(int *a , int *b);
int main()
{
int *p = (int*) malloc(sizeof(int));
int *q = (int*) malloc(sizeof(int));
if (p != NULL && q != NULL)
{
*p =10;
*q =10;
int c = sum(p,q);
printf("%d", c);
free(p);
free(q);
}
else
{
printf("Could not allocate enough memory");
return 1;
}
return 0;
}
int sum(int *a , int *b)
{
return (*a) + (*b);
}
Hope this helps!
A pointer is a variable that holds the address of another variable, and this seems clear to you. But what seems not still very clear is that when you create a pointer the compiler doesn't automagically create also a variable to point to...
In code:
int *p;
int *q;
*p =10;
*q =10;
You are defining p and q as pointers to int, but to which variables of type int they point? They have a garbage inside and can point anywhere, so when assigning 10 to what they point to, in reality, you are spamming somewhere in memory.
Under these conditions when you call sum I would expect more a memory fault than a strange value (255), but everything can happen with bad pointers, even to access an existing memory.
The correct code is:
int sum(int *a , int *b);
int main()
{
int i1, i2; //Allocate 2 int variables
int *p = &i1; //Create pointers and assign them
int *q = &i2; //the address of int vars i1 and i2
*p =10; //Initialize variables pointed by pointers with 10
*q =10;
int c = sum(p,q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}
A pointer needs to be assign the address of some valid memory to point to before it may be dereferenced of the *-operator and gets written some data to where it points to.
You miss those very assignments.
Dereferencing a pointer implies reading out its value. If no value ever had been assigned to a pointer variable, already reading out its value might invoke the infamous Undefined Behaviour, anything can happen after this.
So your result could also have been just the famous 42.
Lesson learned: Never apply any operator to a variable which had not been properly been initialised.
Another approach. I think it may be useless for return function but it can help you about pointers It is passing pointer to the sum function
#include <stdio.h>
int sum(int *a , int *b);
int main()
{
int p = 10;
int q = 10;
int c = sum(&p,&q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}
You're getting 255 is because of random luck. I get 20 when I compile it, but that's also random luck. The technical term is "undefined behavior", and this is undefined because you never initialized your int *p and int *q pointers.
What's inside your pointer variables? You don't know, I don't know, nobody does. Since you never initialized them, their contents are whatever bits were there before initialization. It's like moving into a house and getting whatever junk the previous tenants left for you.
If the contents of the pointers are addresses in memory (and they don't overlap), then the value returned should be 20 (by random luck). But if one of them contains a null address, who knows what you'll get!
If you want to get 20 reliably, you need to allocate memory:
In C++:
int * p = new int;
int * q = new int;
In C:
int * p = (int*)malloc(sizeof(int))
int * q = (int*)malloc(sizeof(int))
This question already has answers here:
Declaring a C function to return an array
(5 answers)
Closed 9 years ago.
I am working on a very basic program where I want to return an integer array of length 2 to my main block. I can't get it to work though, and I was told that I may need pointers to do this. How do pointers work, and how can I use this in my program?
Here is my current code:
int[] return2();
int main() {
int a[2];
a = request();
printf("%d%d\n", a[0], a[1]);
return(0);
}
int[] request ()
{
int a[2];
a[0] = -1;
a[1] = 8;
return a;
}
You can't declare a function returning an array.
ISO/IEC 9899:1999
§6.9.1 Function definitions
¶3 The return type of a function shall be void or an object type other than array type.
C2011 will say essentially the same thing.
You shouldn't ever return a pointer to a (non-static) local variable from a function as it is no longer in scope (and therefore invalid) as soon as the return completes.
You can return a pointer to the start of an array if the array is statically allocated, or if it is dynamically allocated via malloc() et al.
int *function1(void)
{
static int a[2] = { -1, +1 };
return a;
}
static int b[2] = { -1, +1 };
int *function2(void)
{
return b;
}
/* The caller must free the pointer returned by function3() */
int *function3(void)
{
int *c = malloc(2 * sizeof(*c));
c[0] = -1;
c[1] = +1;
return c;
}
Or, if you are feeling adventurous, you can return a pointer to an array:
/* The caller must free the pointer returned by function4() */
int (*function4(void))[2]
{
int (*d)[2] = malloc(sizeof(*d));
(*d)[0] = -1;
(*d)[1] = +1;
return d;
}
Be careful with that function declaration! It doesn't take much change to change its meaning entirely:
int (*function4(void))[2]; // Function returning pointer to array of two int
int (*function5[2])(void); // Array of two pointers to functions returning int
int (*function6(void)[2]); // Illegal: function returning array of two pointers to int
int *function7(void)[2]; // Illegal: function returning array of two pointers to int
You better to understand how does pointer work. Here is a (bad) solution:
#include <stdio.h>
int* request(){
int a[2];
a[0] = -1;
a[1] = 8;
return a;
}
int main() {
int* a;
a = request();
printf("%d%d\n", a[0], a[1]);
return 0;
}
but there is a problem. since int a[2]; in int* request() is a local variable, there is no guarantee that the value returned will not be overwritten.
Here is a better solution:
#include <stdio.h>
void request(int* a){
a[0] = -1;
a[1] = 8;
}
int main() {
int a[2];
request(a);
printf("%d %d\n", a[0], a[1]);
return 0;
}
You have to return pointer to array of 2 integers from function.
#include
int(* request()) [2]
{
static int a[2];
a[0] = -1;
a[1] = 8;
return &a;
}
int main() {
int (*a) [2];
a = request();
printf("%d%d\n", *(*a+0), *(*a+1));
return 0;
}
The array int a[2] that you declare in request is only valid during the scope of that function, so returning it like that doesn't work, since once main gets its hands on it the array is no longer valid.
If you don't understand pointers, you're going to kind of have to to really get what's going on, but here is some code that will do what you want:
int* request();
int main() {
int* a; // a is a pointer to an int
a = request();
printf("%d%d\n", a[0], a[1]);
// we have to tell the program that we're done with the array now
free(a);
return(0);
}
int* request ()
{
// allocate space for 2 ints -- this space will survive after the function returns
int* a = malloc(sizeof(int) * 2);/
a[0] = -1;
a[1] = 8;
return a;
}
You can do as others suggest and allocate memory via malloc to return a pointer. You should also consider something like the following:
struct values {
int val1;
int val2;
};
struct values request();
int main() {
struct values a;
a = request();
printf("%d%d\n", a.val1, a.val2);
return(0);
}
struct values request ()
{
struct values vals;
vals.val1 = -1;
vals.val2 = 8;
return vals;
}
Structures are passed and returned by value (meaning they are copied) and can sometimes be easier and safer depending on the type of data contained within the structures.
To return the array, you must dynamically allocate it.
Try this instead (Observe the changes) :
int* request();
int main() {
int *a;
a = (int *)request();
printf("%d %d\n", a[0], a[1]);
return(0);
}
int* request() {
int *a = malloc(sizeof(int) * 2);
a[0] = -1;
a[1] = 8;
return a;
}