Passing structure by reference through 4 functions

This is a discussion on Passing structure by reference through 4 functions within the C Programming forums, part of the General Programming Boards category; Hi there, I have the following code, listed below. Basically I need to pass a structure by reference through 4 ...

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    8

    Passing structure by reference through 4 functions

    Hi there,

    I have the following code, listed below. Basically I need to pass a structure by reference through 4 functions so that I can change its value in the fourth function and then keep the changed value up to the top.

    The following code is not working (C, Linux). Any help on that would be greatly appreciated.

    Code:
    #include "main.h"
    
    void f1(struct list_type **info)
    {
    	(*info)->type = 1;
    	strcpy((*info)->data, "1");
    
    	f2(&(*info));
    }
    
    void f2(struct list_type ***info)
    {
    	(**info)->type = 2;
    	strcpy((**info)->data, "2");
    
    	f3(&(**info));
    }
    
    void f3(struct list_type ****info)
    {
    	(***info)->type = 3;
    	strcpy((***info)->data, "3");
    
    	f4(&(***info));
    }
    
    void f4(struct list_type *****info)
    {
    	(****info)->type = 4;
    	strcpy((****info)->data, "4");
    }
    
    int main(int argc, char **argv)
    
    {
    	struct list_type *info = NULL;
    	
    	info->data = malloc(sizeof(char) * 100);
    	if (info->data == NULL)
    		return 1;
    
    	info->type = 0;
    	strcpy(info->data, "0");
    
    	f1(&info);
    
    	free(info->data);
    
    	return 0;
    
    }
    Thank you very much.

    Regards,
    Nick

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    1) I don't know why you would ever want to do something like this.

    2) Just in case this is a learning experiment though, you are mixing up referencing with dereferencing when you call the other functions. On each subsequent call to an f you need to pass the address of the current parameter.

    e.g. if info is of type **, &info would be ***.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    There's no need for extra stars as you go along. And you should define "not working".

  4. #4
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    Quote Originally Posted by claudiu View Post
    1) I don't know why you would ever want to do something like this.
    Well... unfortunately it isn't a learning experiment. I wrote a good chunk of code with f1 using a complex version of the structure then passing it to f2(), with the data from structure being read in f3() then in a shared library with additional processing in f4(). After return from f4->f3->f2 to f1 I found out that the structure data was changed locally in f4() only.

    Could you please provide a more explicit answer for f1 and f2 at least.

    Thank you very much.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by nickdavid35 View Post
    Well... unfortunately it isn't a learning experiment. I wrote a good chunk of code with f1 using a complex version of the structure then passing it to f2(), with the data from structure being read in f3() then in a shared library with additional processing in f4(). After return from f4->f3->f2 to f1 I found out that the structure data was changed locally in f4() only.

    Could you please provide a more explicit answer for f1 and f2 at least.

    Thank you very much.
    There's still no need for extra stars as you go along -- a reference to a structure is always and forever "struct list_info *". (If you need to make the pointer point to a different structure -- i.e., if you do malloc/or realloc -- then you need to pass the pointer by reference, which would be "struct list_info **".)

  6. #6
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    Quote Originally Posted by tabstop View Post
    There's no need for extra stars as you go along. And you should define "not working".
    By not working I mean that when I am changing the structure data in f4() the data is changed only locally, it is not "brought back with the new values" to main().

    Thank you very much.

  7. #7
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    I can not use the struct as a return value from f4() or f3() or f2() or f1() as well. I have close to 170 shared libraries all built in the same way, it would be a major effort to rewrite that. I tested some initially, but I did some bad allocations in f4() and valgrind pointed that the memory was leaking.

  8. #8
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    I can pay $50 for that if someone is willing to help me make it work.

  9. #9
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Quote Originally Posted by nickdavid35 View Post
    I can not use the struct as a return value from f4() or f3() or f2() or f1() as well. I have close to 170 shared libraries all built in the same way, it would be a major effort to rewrite that. I tested some initially, but I did some bad allocations in f4() and valgrind pointed that the memory was leaking.
    If you have so many libraries written using pointer-pointer-pointer-pointers I would take all of those libraries put them in the recycle bin and empty it.

    There should be no need to ever use anything beyond a "2nd degree" pointer. (**).
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    No really:
    Code:
    #include <stdio.h>
    
    struct thing {
        int x;
    };
    
    void f4(struct thing *bob) {
        bob->x = 5;
    }
    
    void f3(struct thing *bob) {
        f4(bob);
    }
    
    void f2(struct thing *bob) {
        f3(bob);
    }
    
    void f1(struct thing *bob) {
        f2(bob);
    }
    
    int main(void) {
        struct thing foo;
        foo.x = 2;
        printf("Before: %d\n", foo.x);
        f1(&foo);
        printf("After: %d\n", foo.x);
        return 0;
    }

  11. #11
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Quote Originally Posted by nickdavid35 View Post
    By not working I mean that when I am changing the structure data in f4() the data is changed only locally, it is not "brought back with the new values" to main().

    Thank you very much.
    That's what you think.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    And the version where the function needs to acquire space:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct thing {
        int x;
    };
    
    void f4(struct thing **bob) {
        *bob = malloc(sizeof(**bob));
        (*bob)->x = 5;
    }
    
    void f3(struct thing **bob) {
        f4(bob);
    }
    
    void f2(struct thing **bob) {
        f3(bob);
    }
    
    void f1(struct thing **bob) {
        f2(bob);
    }
    
    int main(void) {
        struct thing *foo;
        foo = NULL;
        printf("Before: %x\n", foo);
        f1(&foo);
        printf("After: %x and value %d\n", foo, foo->x);
        return 0;
    }

  13. #13
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    [QUOTE=tabstop;942397]No really:
    Code:
    #include <stdio.h>
    
    struct thing {
        int x;
    };
    Thank you very much TabStop. How can I send you the funds?

  14. #14
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    Thank you also Claudiu.

  15. #15
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    Final working code, reference for some other people:

    Code:
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    
    struct thing {
        int x;
    	char *y;
    };
    
    void f4(struct thing *bob) {
        bob->x = 4;
    	strcpy(bob->y, "4");
        printf("4: %d, %s\n", bob->x, bob->y);
    }
    
    void f3(struct thing *bob) {
        bob->x = 3;
    	strcpy(bob->y, "3");
        printf("3A: %d, %s\n", bob->x, bob->y);
    
        f4(bob);
        printf("3B: %d, %s\n", bob->x, bob->y);
    }
    
    void f2(struct thing *bob) {
        bob->x = 2;
    	strcpy(bob->y, "2");
        printf("2A: %d, %s\n", bob->x, bob->y);
    
        f3(bob);
        printf("2B: %d, %s\n", bob->x, bob->y);
    }
    
    void f1(struct thing *bob) {
        bob->x = 1;
    	strcpy(bob->y, "1");
        printf("1A: %d, %s\n", bob->x, bob->y);
    
        f2(bob);
        printf("1B: %d, %s\n", bob->x, bob->y);
    }
    
    int main(void) {
        struct thing foo;
    	foo.y = malloc(100);
    
        foo.x = 0;
        strcpy(foo.y, "0");
        printf("0A: %d, %s\n", foo.x, foo.y);
        f1(&foo);
        printf("0B: %d, %s\n", foo.x, foo.y);
    	free(foo.y);
        return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. Compiling C in Visual Studio 2005
    By emanresu in forum C Programming
    Replies: 3
    Last Post: 11-16-2009, 03:25 AM
  3. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  4. passing structure arrays to functions?
    By bem82 in forum C Programming
    Replies: 3
    Last Post: 10-30-2006, 05:17 AM
  5. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 05:58 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21