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;
}
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
}
This question already has answers here:
Returning Arrays/Pointers from a function
(7 answers)
Closed 9 years ago.
Here is my code:
int *myFunction()
{
int A[3] = {1,2,3};
return A; //this will return the pointer to the first element in the array A
}
int main (void)
{
int A[3];
A = myfunction(); //A gets the return value of myFunction
for(int j=0; j==2; j++)
{
B[j] = 2* A[j]; //doubles each value in the array
}
printf("%d",B);
return 0;
}
But this does not work because the A that is returned is not the actual vector. How do I get the actual vector {1,2,3} in the main function?
The function myFunction allocates A, but this allocation only exists within the scope of the function. When the function returns the memory holding A is destroyed. This means that the function is returning a pointer to memory that has not been un-allocated.
The problem is that the variable A does not persist outside the function. You could use a global variable or pass a pointer to the buffer into myFunction
Global variable method:
static int A[3];
int* myFunction()
{
A[0] = 1; A[1] = 2; //etc
return A;
}
In this example, because A is a global, the memory pointed to by A persists throught your program's entire life time. Therefore it is safe to return a pointer to it...
As a side note, global variables should probably not be used in this way... it's a little clunky. The use of the static keyword means that A will not be accessible outside of this module (C file).
Pointer method:
void myFunction(a[3])
{
a[0] = 1; a[1] = 2; //etc
}
int main()
{
myA[3];
myFunction(myA);
// and continue to print array...
}
In this example the main() function allocates myA. This variable exists whilst the function is executing (it's an automatic variable). A pointer to the array is passed into the function, which fills the array. Therefore the main() function can get information from myFunction().
Another way to make the variable myA persist would be to allocate it on the heap. To do this you would do something like int *myA = malloc(sizeof(int) * NUMBER_OF_INTS_IN_ARRAY. This memory will then persist until you specifically desctroy it using free() or you program ends.
int A[3] = {1,2,3}; is being created on the stack, this is, it is a local array and it's memory can be used again after myFunction executes. You have to either make int A[3] static within myFunction or by placing it outside of all functions. Another option would be to create int A[3] within main and pass the address of A to myFunction so myFunction can directly modify the contents of A.
As is, your code isn't close to working anyway... your for loop is broken, you have undefined variables in main, you have function name mismatches, and your print isn't going to do what you want anyway...
The big problem as that you've got undefined behavior going on, you can't access A[] outside of the function where it was locally defined. The easiest way to rectify that is to use dynamic memory, malloc() some memory for A in your myFunction then use the values in main and free() the memory when you're done.
Here's the example fixing your other syntax issues:
int *myFunction()
{
int *A;
A = malloc(3 * sizeof(int));
A[0] = 1;
A[1] = 2;
A[2] = 3;
return A;
}
int main (void)
{
int *A = myFunction(); //A gets the return value of myFunction
int B[3] = {0, 0, 0};
int j;
for(j=0; j<3; j++)
{
B[j] = 2* A[j]; //doubles each value in the array
}
free(A);
printf("%d",B[0]);
return 0;
}
Pass the array to be filled as argument to the initisliser function along with its size:
size_t myFunction(int * A, size_t s)
{
int A_tmp[3] = {1,2,3};
size_t i = 0;
for (; i < s && i < sizeof(A_tmp)/sizeof(A_tmp[0]); ++i)
{
A[i] = A_tmp[i];
}
return i;
}
Then call it like so:
int main()
{
int myA[3];
size_t s = sizeof(myA)/sizeof(myA[0]);
size_t n = myFunction(myA, s);
if (n < s)
fprintf(stderr, "Caution: Only the first %zu of %zu elements of A were initialised.\n", n, s);
// and continue to print array...
}
#include <stdio.h>
int (*myFunction(void))[3]
{
static int A[3] = {1,2,3};
return &A;
}
int main (void){
int (*A)[3], B[3];
A = myFunction();
for(int j=0; j<=2; j++)
{
B[j] = 2 * (*A)[j];
}
for(int j=0; j<3;++j)
printf("%d ", B[j]);
return 0;
}
I want to make a function pointer array and be able to call them in a for-loop. How can I achieve this? I have tried:
void (**a) (int);
a[0] = &my_func1;
a[1] = &my_func2;
a[2] = &my_func3;
for ( i = 0; i < 3; i++){
a[0]();
(*a[0])(); // Neither does work
}
But I am missing some syntax I guess:
error: too few arguments to function ‘*(a + (long unsigned int)((long unsigned int)i * 8ul))’
The function you declare is expected to take an int as a parameter:
a[0](1);
Also note that you declare a pointer to pointer for the functions, but you don't allocate any memory for them (I assume this is only in the example) Otherwise it should probably be:
void (*a[3]) (int);
You are declaring that a is a pointer to a pointer to (or an array of pointers to) a function that takes an int as a parameter - so you need to pass an int when you call the functions, e.g. a[0](42);.
I guess the below code is what you need.
typedef void * func_pointer(int);
func_pointer fparr[10];
for(int i = 0; i<10; i++)
{
fparr[i](arg); //pass the integer argument here
}
1) Where have you allocated or defined array to store function addresses?
2) in loop you are always calling (*a[0])();,There should be loop counter
You forgot to give an argument to your function.
void (**a) (int); // here it takes an int argument
a[0] = &my_func1;
a[1] = &my_func2;
a[2] = &my_func3;
for ( i = 0; i < 3; i++){
a[0](); // here you do not give an argument
}
But be careful, you do not allocate memory to your a array, and it fails with a nice segmentation fault error.
void my_func1(int i) {
;
}
void my_func2(int i) {
;
}
void my_func3(int i) {
;
}
int main() {
void (**a) (int);
a = malloc(3*sizeof(void*)); // allocate array !
a[0] = &my_func1;
a[1] = &my_func2;
a[2] = &my_func3;
for (int i = 0; i < 3; i++){
a[i](1); // respect your own function signature
}
free(a); // it's always a good habit to free the memory you take
return 0;
}
You can typedef void (*pfun)(int); and then pfun a[3]; is the array you want.
The following code may work for you:
typedef void (*pfun)(int);
int main() {
pfun a[3];
a[0] = myfunc1; // or &myfunc1 whatever you like
a[1] = myfunc2;
a[2] = myfunc3;
}
You can define your function-array with the needed size and initialize it with your functions like:
void my_func1(int x){}
void my_func2(int x){}
void my_func3(int x){}
void (*a[])(int)={my_func1,my_func2,my_func3};
int i;
for(i=0;i<sizeof a/sizeof*a;++i)
a[i](i);
The address-operator '&' before any function-name is redundant.
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.
I have the following code:
int takeEven(int *nums, int numelements, int *newlist) {
newlist = malloc(numelements * sizeof *newlist);
int i, found = 0;
for(i = 0; i < numelements; ++i, nums++) {
if (!(*nums % 2)) {
*(newlist++) = *nums;
found++;
}
}
newlist -= found;
printf("First number found %d\n", *newlist); // <= works correctly
return found;
}
int main()
{
int nums[] = {1,2,3,4,5};
int *evenNums;
int i;
int n = takeEven(nums, sizeof(nums) / sizeof(*nums), evenNums);
for (i = 0; i < n; ++i) {
printf("%d\n", *(evenNums++));
}
return 0;
}
The output of the above code:
-1
2088999640
2088857728
If I try printing the first element of the newlist pointer before returning the function (printf("First number found %d\n", *newlist);), it works as intended, but why is it that when I try to access the pointer from outside of the function I get those values from seemingly unmalloced addresses?
You are passing the newList pointer by value, so it will not be modified by your function. You should do instead.
int takeEven(int *nums, int numelements, int **newlist) {
*newlist = malloc(numelements * sizeof *newlist);
...
}
...
int n = takeEven(nums, sizeof(nums) / sizeof(*nums), &evenNums);
You need to pass in a pointer to pointer, i.e. int **newlist. Specifically, newlist is being passed into your function by value, so the newlist in main and inside your function are two completely different variables.
There is also a bug in your test for even numbers:
#include <stdio.h>
#include <stdlib.h>
int takeEven(int *nums, int numelements, int **newlist) {
int *list = malloc(numelements * sizeof **newlist);
*newlist = list; // this modifies the value of newlist in main
int i, found = 0;
for(i = 0; i < numelements; ++i, nums++) {
if ((*nums % 2) == 0) {
*(list++) = *nums;
found++;
}
}
list -= found;
printf("First number found %d\n", *list); // <= works correctly
return found;
}
int main()
{
int nums[] = {1,2,3,4,5};
int *evenNums;
int i;
int n = takeEven(nums, sizeof(nums) / sizeof(*nums), &evenNums);
for (i = 0; i < n; ++i) {
printf("%d\n", *(evenNums++));
}
return 0;
}
You can also take a look at this question from the C-FAQ which deals with your problem also:
Q: I have a function which accepts, and is supposed to initialize, a pointer:
void f(int *ip)
{
static int dummy = 5;
ip = &dummy;
}
But when I call it like this:
int *ip;
f(ip);
the pointer in the caller remains unchanged.
A: Are you sure the function initialized what you thought it did? Remember that arguments in C are passed by value. In the code above, the called function alters only the passed copy of the pointer. To make it work as you expect, one fix is to pass the address of the pointer (the function ends up accepting a pointer-to-a-pointer; in this case, we're essentially simulating pass by reference):
void f(ipp)
int **ipp;
{
static int dummy = 5;
*ipp = &dummy;
}
...
int *ip;
f(&ip);
Another solution is to have the function return the pointer:
int *f()
{
static int dummy = 5;
return &dummy;
}
...
int *ip = f();
See also questions 4.9 and 4.11.
The newlist you have at the end of the function is not the same as you have when calling the function.
You are passing a copy of a pointer, then malloc changes that pointer(internal to the function) to point to allocated memory, but the outside one is still unmodified.
You need to use a pointer to pointer as a parameter so that you can set where the ourtside one points by double indirection.
int use_pointed_memory(char **pointer){
*pointer = malloc();
}
char *myptr;
use_pointed_memory(&myptr);
So effectively you are giving the function the place where you store the address of what you want and asking the function to store there a valid memory pointer.
You're passing a pointer by value here:
int n = takeEven(nums, sizeof(nums) / sizeof(*nums), evenNums);
Which means that a copy of the pointer is made within that function. You then overwrite that copy:
newlist = malloc(numelements * sizeof *newlist);
Since it is but a copy, the caller won't see the result of your assignment. What you seemingly want here is to pass a pointer by reference - for that, you need a pointer to pointer:
int takeEven(int *nums, int numelements, int **newlist) {
*newlist = malloc(numelements * sizeof **newlist); // apply * to newlist
...
}
int n = takeEven(nums, sizeof(nums) / sizeof(*nums), &evenNums);
And don't forget to free:
free(evenNums);
In C, everything is passed by value. So you are passing a copy of evenNums to the function. Whatever you modify it inside the function doesn't get reflected outside. You need to int** as the third parameter.