简体   繁体   中英

How can I use pointers to structure elements?

I have the following "test code":

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

struct data{
  char *name;
  void *value;
};

struct g_arg{
  char *info1;
  char *info2;
  int info3;
};


int main()
{
  char *some_info = "information to store in g";

  struct g_arg g;

  struct data d[] = {
    {"info1=", &g.info1},
    {"info2=", &g.info2},
    {"info3=", &g.info3},
    {NULL, NULL},
  };

  ...

}

I want to insert a value in the g struct elements, passing through d struct. For instance, I'd like to make something like this:

d[0].value = some_info;

After the execution of this instruction, g.info1 should contains the string some_info.

This is only an example code. I have to make something similar in a complex program. I searched for other questions like this, but I don't find a solution.


Thank you to all of you guys. I make some progress, but the problem is not solved yet. I'll try to explain a little better. Now, if I do this:

printf( "content of g.info1: %s", (char*)(d[0].value) );

I can read the content of g.info , by accessing to d structure. But I need to write inside g.info , by "writing" something in d[i].value .

your g_arg pointers info1 and info2 need to be tied to some memory to be able to assign to them latter.

Since those are pointers, you cannot assign one string to another, so use some thing like strcpy.

Also if you know the sizes, you can make info1 and info2 as char arrays instead of having to dynamically allocate memory for them.

Point 1. allocate memory to g.info1 using malloc() [or family].

Point 2 . use strcpy() to copy the data to d[0].value

Point 3. You don't need to use &g.info1 , g.info1 will suffice.

In your code, g.info1 has type char * , so &g.info1 has type char ** . You can certainly assign that to the void * element value of a struct data , but it is a pointer to a (maybe) string, not a string itself.

Moreover, the result is a pointer to a stack-allocated pointer. If this pointer value survives past the end of the function then it will cease to be valid, and any attempt to dereference it will produce undefined behavior.

If you want to copy string values into elements of array d instead of assigning pointers to them as you now do, then you must first have strings to copy. In that case, you can use strdup() to allocate space and copy the string in one step:

struct g_arg g = { "info 1", "info 2", 42 };

struct data d[] = {
    {"info1=", NULL},
    {"info2=", NULL},
    {"info3=", NULL},
    {NULL, NULL},
};
d[0].value = strdup(g.info1);
d[1].value = strdup(g.info2);
d[2].value = malloc(sizeof(int));
*((int *) d[2].value) = g.info3;

Note that in this case, all the resulting pointers recorded in the value members of elements of d refer to dynamically allocated memory. This allows them to remain valid past the function's exit, but it requires the program to later free() them to avoid leaking memory.

wrt to d[0].value = some_info; this would in theory work if some_info was already an object of type struct g_arg whose member info1 was already set to a string.

But it seems that you want some_info to be a string ( char * , C style);

So you'll need to reference the info1 member of d[0].value . So you'll need to cast the void* to the appropriate data type (struct g_arg *)(d[0].value) and then access the member info1 , like so: ((struct g_arg *)(d[0].value))->info1 .

Since info1 is a char * you should use strdup() to copy the string into an appropriately allocated buffer or manually allocate the memory for the string before copying. You end up with this:

((struct g_arg *)(d[0].value))->info1 = strdup(some_info);

Remember to free() the memory when you're done.

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