1

If I have the following C struct:

struct group_of_pointers {
    double *p1, *p2, *p3;
} *pointers;

Now, I want to allocate n spaces (each with sizeof double) to pointers->p1, pointers->p2, pointers->p3. How do I do this? Do I have to allocate any space to the pointer to the structure 'pointers' itself?

Thanks.

ETA: Related question: The reason I need this struct is because I want to return 3 variable length arrays from a function. Should I just do

void foo(const double* const input, double *output1, double *output2, double *output3) 

or should I do

struct group_of_pointers *foo(const double* const input)

The former looks a bit confusing with input and output all bundled together. But is it just the way C is?

cinny
  • 2,292
  • 3
  • 18
  • 23

5 Answers5

3

Yes, you have to allocate space for the structure of pointers first. Then you allocate for each component.

pointers = malloc(sizeof *pointers);
pointers->p1 = malloc(n * sizeof(double));
pointers->p2 = malloc(n * sizeof(double));
pointers->p3 = malloc(n * sizeof(double));
Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
2

Yes, since your pointers variable is itself a pointer, you need to give it some memory to point to.

struct group_of_pointers {
    double *p1, *p2, *p3;
} *pointers;

pointers = malloc(sizeof(*pointers));

pointers->p1 = malloc(n*sizeof(*pointers->p1));
pointers->p2 = malloc(m*sizeof(*pointers->p2));
pointers->p3 = malloc(o*sizeof(*pointers->p3));
Kevin
  • 53,822
  • 15
  • 101
  • 132
1

If I'm reading your question correctly, yes, you need the 'pointers' struct to have space, either allocated or on the stack, and you malloc()-or-variant-thereof the space for p1 - p3:

struct group_of_pointers *pointer = malloc(sizeof(*pointer));

pointer->p1 = malloc(n * sizeof(double));
pointer->p2 = malloc(n * sizeof(double));
pointer->p3 = malloc(n * sizeof(double));

/* do stuff here... */

free(pointer->p1);
free(pointer->p2);
free(pointer->p3);
free(pointer);

Of course, I never checked for malloc failure in there, so this code is not to be considered production-ready!

tbert
  • 2,089
  • 13
  • 14
  • Sounds good. The reason I need this struct is because I want to return 3 variable length arrays from a function. Should I just do void foo(*input, *output1, *output2, output3*) or should I do struct group_of_pointers *foo(*input)? – cinny Jan 24 '12 at 19:59
  • Either of those is functional, but I find returning a struct pointer more straightforward. I'm assuming that whatever real struct you're using will have a descriptive name (e.g., spatial_point), and the three floats will have names themselves (e.g., x/y/z_axis) which will lend a little more clarity. – tbert Jan 24 '12 at 20:34
1

What are you trying to do? Do need a struct that can point to three double values? Then yes, you need to allocate memory for any of those objects:

#include <stdio.h>
#include <stdlib.h>

struct group_of_pointers {
    double *p1, *p2, *p3;
} *pointers;

int main(int argc, char *argv[]) {

   pointers = malloc(sizeof(struct group_of_pointers));
   pointers->p1 =  malloc(sizeof(double));
   pointers->p2 =  malloc(sizeof(double));
   pointers->p3 =  malloc(sizeof(double));

   *(pointers->p1) = 10.0;
   *(pointers->p2) = 20.0;
   *(pointers->p3) = 30.0;

   printf("%lf %lf %lf\n", *(pointers->p1), *(pointers->p2), *(pointers->p3));

   return EXIT_SUCCESS;
}
Mithrandir
  • 24,869
  • 6
  • 50
  • 66
  • Tha cast, in C, is, at best, redundant, and may hide an error the compiler would have caught in its absence. – pmg Jan 24 '12 at 19:45
1

if those three arrays are highly related, and you use them often as a group you should use the second approach, but instead of creating a structure on the heap you should create it on the stack then pass its pointer to your function, like

void foo(struct group_of_pointers *ptr, const double *input);

jFuad
  • 11
  • 2
  • What is the difference between the heap and the stack? – cinny Jan 24 '12 at 20:18
  • So it is common for C functions to be all 'void', without clear output? – cinny Jan 24 '12 at 20:19
  • the stack is where you just create variables like: struct group_of_pointers test; then we have a structure test with members i can access like test.p1; test.p2 – jFuad Jan 24 '12 at 20:21
  • Should the initialization for ptr happen inside foo or outside of foo? – cinny Jan 24 '12 at 20:28
  • and I made the function void because there was nothing you wanted to return as far as i am concerned. – jFuad Jan 24 '12 at 20:28
  • What if foo is only called by another sub-function, and the output stays inside that other function only? – cinny Jan 24 '12 at 20:29
  • Before this function, ptr.p1, ptr.p2, ptr.p3 don't have anything. This function uses things inside input to calculate some numbers for ptr.p1, ptr.p2, ptr.p3. Does this make sense? – cinny Jan 24 '12 at 20:30
  • since i used a structure created on the stack, its memory is already valid and can be accessed, this wouldn't have been the case if it was on the heap and i had to allocate memory for it. if foo is a function you call before using the structure, then it is best to initialize it inside foo, it will be called for every structure you create and that insures what you want is done every time – jFuad Jan 24 '12 at 20:31
  • yes it does, you create your struct based on the input. You could even make the return value bool if you are using c++ and return true when there was a successful initialization of the struct or false when there was an error with the input – jFuad Jan 24 '12 at 20:35
  • So it is common that both input and output variables stay on the right hand side of the function call? – cinny Jan 24 '12 at 20:40
  • If I initialize the pointers inside foo, then I'll still have to free them outside - would that make it confusing? – cinny Jan 24 '12 at 20:40
  • almost every time, you don't want to return anything bigger than maybe a double in size, if that happens just pass its pointer to the function, then modify if inside the function using the pointer, that is a lot more efficient – jFuad Jan 24 '12 at 20:42
  • Can you explain why that is more efficient? Also, is it common to have multiple global variables in C that are used by multiple functions in the same file? – cinny Jan 24 '12 at 20:46
  • most of the time you would have two functions, one for the initialization and other for the cleanup, so everything you have allocated on foo must be mirrored by a cleanup function that frees the space i tried to move this on the chat but there is a problem with my connection, anyways it is more effiecient because a pointer will only cost you 4-bytes on a 32-bit system where as your structures would have cost 3*sizeof(double*)==12-bytes and as the structures gets bigger and bigger, passing and returning the whole structure would require a lot more memory – jFuad Jan 24 '12 at 20:52
  • Okay, I think it's better if I start a more thorough question: http://stackoverflow.com/questions/8994069/global-variables-and-return-multiple-variable-length-arrays-pointers-in-c-func – cinny Jan 24 '12 at 20:59