Reputation: 130
I'm trying to return 4 pointers which are stored in another pointer from a function in C, but I get segmentation fault. Do anyone know how to do this?
That's the way I tried to do this:
//declaration of 5 pointers (int * ptr0, float * ptr1, ..., int * ptr4)
int * function()
{
int * ptr;
ptr = malloc(sizeof(int)*4);
float * ptr1;
ptr1 = malloc(sizeof(float)*4);
float * ptr2;
ptr2 = malloc(sizeof(float)*4);
float * ptr3;
ptr3 = malloc(sizeof(float)*4);
int * ptr4;
ptr4 = malloc(sizeof(int)*4);
retunr ptr;
}
ptr0 = function();
ptr1 = ptr0[0];
ptr2 = ptr0[1];
//and so on...
Ok, I changed my program but now I can not write in the pointers anymore. I know this is a realy 'stupid' question but I realy dont know. Can someone help ?
Upvotes: 2
Views: 4848
Reputation: 10880
You didn't fill *ptr, but even if you did, don't do this. Use std::tuple<>
or pair of std::pair<>
s - or return a struct.
Edit: since it's no more C++, just return a struct with the four fields.
Upvotes: 1
Reputation: 238311
You can only return a singe value from a function. A simple solution is to return a struct that contains the desired pointers.
struct pointers {
float* ptr1;
float* ptr2;
float* ptr3;
// or perhaps an array instead:
// float* f_ptrs[3];
int* ptr4;
}
struct pointers function() {
struct pointers p;
// initialize the members here
return p;
}
Upvotes: 9
Reputation: 70893
What about this:
#include <stdlib.h>
#include <stdio.h> /* for perror() */
int function(void ** ptrs, size_t n)
{
int result = -1;
pptrs[0] = malloc(...);
if (NULL == ptrs[0])
{
goto err;
}
...
ptrs[n - 1] = malloc(...);
if (NULL == ptrs[n - 1])
{
goto err;
}
result = 0;
err:
return result;
}
int main(void)
{
size_t n = 5;
void * ptrs[n];
for (size_t i = 0; i < n; ++n)
{
ptrs[n] = NULL;
}
if (-1 == function(ptrs, n))
{
perror("function() failed");
exit(EXIT_FAILURE);
}
/* Do stuff. */
/* Free memory where ptrs' are pointing to. */
return EXIT_SUCCESS;
}
If VLAs are not supported change the beginning of main()
to be:
#define N (5)
int main(void)
{
size_t n = N;
void * ptrs[N] = {0};
if (-1 == function(ptrs, n))
{
...
Upvotes: 1
Reputation: 2324
i saw it wasn't mentioned, but you could also pass double pointers into the function and have the function fill them out, another way to return multiple values:
void function(int** p1, float** p2, float** p3, float** p4, int** p5)
{
*p1 = malloc(sizeof(int)*4);
*p2 = malloc(sizeof(float)*4);
*p3 = malloc(sizeof(float)*4);
*p4 = malloc(sizeof(float)*4);
*p5 = malloc(sizeof(int)*4);
}
int* ptr1;
float* ptr2;
float* ptr3;
float* ptr4;
int* ptr5;
function(&ptr1, &ptr2, &ptr3, &ptr4, &ptr5);
Upvotes: 3
Reputation: 21258
There are three choices, you could return a void**
(basically, a pointer to an array of void*
that you then cast), you can declare a struct that contain the pointers, then allocate and return a pointer to such a struct (then let the caller de-allocate the struct) or you can use a func(float **ptr0, float **ptr1, float **ptr2, int **ptr3)
and assign your malloced memory to *ptr0
, ...
Neither of these are perfect, depending on circumstances I would pick either solution 2 or solution 3, on the basis that it's going to end up messy remembering all the relevant casts and allowing the compiler to help you with types is a good idea.
Upvotes: 2
Reputation: 2214
void ** function()
{
void ** ptr;
ptr = (void **)malloc(sizeof(void *)*4);
ptr[0] = malloc(sizeof(float)*4);
ptr[1] = malloc(sizeof(float)*4);
ptr[2] = malloc(sizeof(float)*4);
ptr[3] = malloc(sizeof(int)*4);
return ptr;
}
Upvotes: 4