简体   繁体   中英

Return multiple pointers from function

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 ?

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;
}
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;
}

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.

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.

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);

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))
  {
    ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM