# Thread: what does this question mean? and solution please!

1. ## what does this question mean? and solution please!

Given a pointer to member a within a struct, write a routine that returns a pointer to the struct.
Code:
```
struct s
{
...
int a;
…
};

struct s *get_s_ptr(int *a_ptr){
}```

2. You should read this before posting:

C Board - Announcements in Forum : C Programming

No one's going to give you the solution for this - we don't do homework for people. Have you learnt what a struct is? Do you know what a member is? Do you understand the relationship between them? Do you know what a pointer is?

You need to show an effort to find your own answers, show what you have so far, and ask a specific question.

3. Thank you for reminding me of this.

I tried to solve this question, however I dont fully understand why the parameter of function is a pointer to member of the struct and return a pointer to the struct. Here is my answer:

Code:
```typedef struct s* sptr;
sptr get_s_ptr(int *a_ptr)
{
sptr ptr;

ptr = malloc(sizeof(sptr));
ptr->a = *a_ptr; //NOT SURE FOR HERE
return ptr;
}```
Thanks for any help!

Originally Posted by sean
You should read this before posting:

C Board - Announcements in Forum : C Programming

No one's going to give you the solution for this - we don't do homework for people. Have you learnt what a struct is? Do you know what a member is? Do you understand the relationship between them? Do you know what a pointer is?

You need to show an effort to find your own answers, show what you have so far, and ask a specific question.

4. You are creating a new struct and setting some of its members. You need to return a pointer to the struct that already exists.

5. Okay, a couple of thoughts:

1) Any time something is malloc()'ed, it needs to be free()'ed, otherwise your program ends up leaking memory. Best practice it to do both calls in the same function. If you really do need to share objects in dynamic memory between functions, either make it global, or declare it in main and pass it to your child functions.

2) What you're trying is a good idea, but I'm afraid it won't work (unless I don't understand that problem). When you call malloc(), it's assigning you a new space in memory. Just because you assign some other address to one of the members, doesn't move the whole struct to that location. Again, this may because I don't fully understand the problem - are there any other details you can provide? Like, what type is sptr.a? If the problem is what I think it is, you really need more details to solve it because you'd need to either a) know how memory is structured in your struct or b) have references to all the current instances of that struct.

Sorry if that's not helpful - but based on the current information, I don't see how that's solvable.

6. Originally Posted by sean
If the problem is what I think it is, you really need more details to solve it because you'd need to either a) know how memory is structured in your struct or b) have references to all the current instances of that struct.
(Or the ability to look up "offsetof".)

7. Yes, you pointed out what I am thinking now. One thing is that how I could "move the whole struct to that location of member a within a struct" passed by the pointer. Is it possible to do that? Otherwise, what's this question asking about? For memory leaking, I could free memory in the test program. Unfortunately, that's all info for this question.
Originally Posted by sean
Okay, a couple of thoughts:

1) Any time something is malloc()'ed, it needs to be free()'ed, otherwise your program ends up leaking memory. Best practice it to do both calls in the same function. If you really do need to share objects in dynamic memory between functions, either make it global, or declare it in main and pass it to your child functions.

2) What you're trying is a good idea, but I'm afraid it won't work (unless I don't understand that problem). When you call malloc(), it's assigning you a new space in memory. Just because you assign some other address to one of the members, doesn't move the whole struct to that location. Again, this may because I don't fully understand the problem - are there any other details you can provide? Like, what type is sptr.a? If the problem is what I think it is, you really need more details to solve it because you'd need to either a) know how memory is structured in your struct or b) have references to all the current instances of that struct.

Sorry if that's not helpful - but based on the current information, I don't see how that's solvable.

8. (Or the ability to look up "offsetof".)
You totally got my hopes up there. I was all excited, thinking I just learned a new keyword in C. But you totally jogged my brain the right war - I just realized how to solve the problem, and started kicking myself.

So, ljin: When you declare a struct, it's basically just an area of memory, and the compiler understands that the first few bytes of the struct are for one member, the next byte is for some char, etc... So all you need to know to get the pointer of the struct from the pointer to the member, is the "offset" of that member. Does that make sense? You could calculate the difference with some "test" instance, and then just apply the same difference to the pointer you were given.

9. Originally Posted by sean
You totally got my hopes up there. I was all excited, thinking I just learned a new keyword in C. But you totally jogged my brain the right war - I just realized how to solve the problem, and started kicking myself.
Now I'm confused. "offsetof" is a keyword in C (well, actually, a predefined macro).

10. Oh nice. Yeah I just did a quick google search and it seemed that there few enough relevant results that it must just be one of those "Turbo C-only" things. I didn't realize it was actually standard - I can't believe I didn't know that before.

11. Originally Posted by tabstop
Now I'm confused. "offsetof" is a keyword in C (well, actually, a predefined macro).
oh man....offsetof <---- a so good macro

after reading from top post .... now I'm confused, too. o.O;;

12. Thanks guys!

Here is my new trial:

Code:
```typedef struct s* sptr;

struct s{
char c;
int a;
};

...

sptr get_s_ptr(int *a_ptr)
{
sptr ptr;

ptr = malloc(sizeof(sptr));
ptr = a_ptr - sizeof(char); //ANY COMMENT FOR THIS PART, NOT SURE...I just tried the simple case and did not use "offsetof"
ptr->a = *a_ptr;
return ptr;
}```
I got warning msg : assignment from incompatible pointer type.

Thanks you all again!
Originally Posted by sean
You totally got my hopes up there. I was all excited, thinking I just learned a new keyword in C. But you totally jogged my brain the right war - I just realized how to solve the problem, and started kicking myself.

So, ljin: When you declare a struct, it's basically just an area of memory, and the compiler understands that the first few bytes of the struct are for one member, the next byte is for some char, etc... So all you need to know to get the pointer of the struct from the pointer to the member, is the "offset" of that member. Does that make sense? You could calculate the difference with some "test" instance, and then just apply the same difference to the pointer you were given.

13. Originally Posted by ljin
Thanks guys!

Here is my new trial:

Code:
```typedef struct s* sptr;

struct s{
char c;
int a;
};

...

sptr get_s_ptr(int *a_ptr)
{
sptr ptr;

ptr = malloc(sizeof(sptr));
ptr = a_ptr - sizeof(char); //ANY COMMENT FOR THIS PART, NOT SURE...
ptr->a = *a_ptr;
return ptr;
}```
Thanks you all again!
Score: 0/20

You need to not leak a whole structure every time you call the function--that malloc call gets you some memory, which you immediately lose on the next line by reassigning ptr. So now you have a new structure and no way to access it, or give it back to the system, or anything. You also need to examine why we've been talking about offsets, rather than arbitrarily deciding that the offset is 1.

14. Code:
`ptr = a_ptr - sizeof(char);`
You've got the right idea going, but that isn't a reliable way to calculate the off-set. Just because char c is before int a in the definition, doesn't mean your implementation is going to arrange it that way in memory (though it _might_). It will rearrange things depending on how they fit best. You would need to use offsetof() (thanks, tabstop!) or create a new instance and compare the value of a pointer to a with the value of a pointer to your struct.

Code:
`ptr->a = *a_ptr;`
That line isn't necessary. If ptr is moved to the correct location, ptr->a will automatically point to the correct location also. Adding "->a" just adds an offset to ptr. A good test to see if it worked, though, is to see if (ptr->a == a_ptr) evaluates as true.

15. Thanks sean and tabstop!

It does make more sense for me now.

Code:
```sptr get_s_ptr(int *a_ptr)
{
sptr ptr;

ptr = malloc(sizeof(sptr));
ptr = (sptr)((char*)a_ptr - offsetof(struct s, a));//good?
return ptr;
}```
It's better to use offsetof() for some aligned issues. I could free memory in the main. Thanks for great help!

Originally Posted by sean
Code:
`ptr = a_ptr - sizeof(char);`
You've got the right idea going, but that isn't a reliable way to calculate the off-set. Just because char c is before int a in the definition, doesn't mean your implementation is going to arrange it that way in memory (though it _might_). It will rearrange things depending on how they fit best. You would need to use offsetof() (thanks, tabstop!) or create a new instance and compare the value of a pointer to a with the value of a pointer to your struct.

Code:
`ptr->a = *a_ptr;`
That line isn't necessary. If ptr is moved to the correct location, ptr->a will automatically point to the correct location also. Adding "->a" just adds an offset to ptr. A good test to see if it worked, though, is to see if (ptr->a == a_ptr) evaluates as true.

Popular pages Recent additions