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

  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    12

    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. #2
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    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. #3
    Registered User
    Join Date
    Aug 2009
    Posts
    12
    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!

    Quote Originally Posted by sean View Post
    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. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    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. #5
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    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. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by sean View Post
    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. #7
    Registered User
    Join Date
    Aug 2009
    Posts
    12
    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.
    Quote Originally Posted by sean View Post
    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. #8
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    (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. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by sean View Post
    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. #10
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    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. #11
    Registered User
    Join Date
    May 2009
    Posts
    60
    Quote Originally Posted by tabstop View Post
    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. #12
    Registered User
    Join Date
    Aug 2009
    Posts
    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!
    Quote Originally Posted by sean View Post
    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.
    Last edited by ljin; 08-13-2009 at 09:21 AM.

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by ljin View Post
    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. #14
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    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. #15
    Registered User
    Join Date
    Aug 2009
    Posts
    12
    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!

    Quote Originally Posted by sean View Post
    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 subscribe to a feed