28

I am trying to work out a double pointer to a structure in C and cannot figure out what is going wrong... The simple source is below:

typedef struct
{
    int member;
} mystruct;

void myfunc(mystruct **data)
{
    (*data)->member = 1;
}

void main(int argc, char *argv[])
{
    mystruct **data;

    myfunc(data);

    printf("member = %d\n", (*data)->member);
}

A similar question was asked here: How to work with pointer to pointer to structure in C? on how to modify a member of a structure through a double pointer. The solution was the syntax (*data)->member = 1; which makes sense. But in my little application here, I receive a seg fault when executing that line. What am I doing wrong?

Thanks

Community
  • 1
  • 1
linsek
  • 3,334
  • 9
  • 42
  • 55
  • 4
    Allocation aside, +1 for a well asked question. – Kelly S. French Oct 03 '11 at 17:44
  • 2
    Normally, the only reason you would use a pointer to a pointer to a struct would be a function needs to change where a pointer points. For example, if `myfunc` were allocating instances of `mystruct` or perhaps retrieving them from a list/queue/etc, it would make sense. But if you are only manipulating the content of the struct, there's no reason for a 'double pointer'. – Brian McFarland Oct 03 '11 at 17:51
  • 1
    to put some context on this, I am not trying to create this. I am trying to create a USB interface using libusb-1.0. One of the libraries functions requires a double pointer to a structure as an argument. So I was trying to work out how I was going to provide that. Everyone has been dead on with their responses though. Thanks! – linsek Oct 03 '11 at 17:58

6 Answers6

24

You need to point to something if you are going to dereference a pointer. Try this:

void main(int argc, char *argv)
{
    mystruct actualThing;
    mystruct *pointer = &actualThing;
    mystruct **data = &pointer;
    myfunc(data);

    printf("Member: %d", (*data)->member);
}
DwB
  • 37,124
  • 11
  • 56
  • 82
7

You received a segfault because you did not allocate a struct.

The value of data is garbage, so it is pointing to some place in memory that is not owned by your process, or is otherwise inaccessible.

You need to first allocate an object of type mystruct. Here is a working example for you: http://ideone.com/XIdJ8

Ray Toal
  • 86,166
  • 18
  • 182
  • 232
5

data is not initialized, and hence doesn't point to any sensible memory address. Moreover, there is no mystruct structure floating around, so there really isn't even any sensible data to point to. For your example, you want to:

  1. Create a mystruct.
  2. Make a pointer to it.
  3. Make a pointer to that pointer.
gspr
  • 11,144
  • 3
  • 41
  • 74
1

Or maybe you can try this:

void main(int argc, char*argv[])
{
   mystruct *data;
   myfunc(&data);
   printf("member = %d\n", data->member);
}

This works for me in C++ and not needed to point another variable.

1

If you only need to pass the double pointer to a library function, you don't need to create a variable for it. You make a normal pointer variable, initialize it to point to appropriate storage (if required by the function), then pass the address of the pointer (thus creating the double-pointer "on the fly").

I've never used libusb, so I'll give an example using a standard library function. From the manpage:

   #include <stdlib.h>

   long int strtol(const char *nptr, char **endptr, int base);

It only looks like a double-pointer. It's really a simulated-pass-by-reference single pointer. Allowing the function to return extra information besides its normal return value. strtol returns a long integer but it also can tell you at what point the string contents stopped looking like a number.

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

int main(void) {
    char *str = "99RED BALLOONS";
    char *what;
    long num;

    num = strtol(str, &what, 10);
    printf("Quantity: %ld;    Description: %s;\n", num, what);

    return 0;
}

Output:

Quantity: 99;    Description: RED BALLOONS;
luser droog
  • 18,988
  • 3
  • 53
  • 105
0

You're passing it a pointer, but the pointer isn't pointing at anything.

This may be more useful:

void main(int argc, char *argv[])
{
    mystruct data;
    mystruct *ptr = &data;
    myfunc(&ptr);
    printf("member = %d\n", (*ptr)->member);
}
Chris Eberle
  • 47,994
  • 12
  • 82
  • 119