Thread: Pass structure by reference(?)

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    12

    Pass structure by reference(?)

    Hello everyone.

    Long time reader, first time poster here. I had been interested in studying C for a long time and just recently finally decided to do so. Also been going through the tutorial given here in this site and I have learned alot. Did some simple programs and decided to make something a bit more challenging.

    What I created below is a simple program that pass structures by reference (I hope I worded it right). This is actually a simplified version of a part of a code that I just saw(which is how I understood it).

    Code:
    #include <stdio.h>
    #include <string.h>
    
    typedef struct
    {
            struct numbers
            {
                    int num1;
                    int num2;
                    int num3;
            } num;
    
            struct letters
            {
                    char let1[2];
                    char let2[2];
                    char let3[2];
            } let;
    } holder;
    
    typedef struct
    {
            struct numbers2
            {
                    int num1;
                    int num2;
                    int num3;
            } num;
    
            struct letters2
            {
                    char let1[2];
                    char let2[2];
                    char let3[2];
            } let;
    } holder2;
    
    typedef struct
    {
            holder *struct1;
            holder2 *struct2;
    } allstruct;
    
    void addnum(allstruct* addold, allstruct* addnew)
    {
            addnew->struct1->num.num1 = (addold->struct1->num.num1) + 1;
            addnew->struct1->num.num2 = (addold->struct1->num.num2) + 2;
            addnew->struct1->num.num3 = (addold->struct1->num.num3) + 3;
    }
    
    void pluslet(allstruct* oldlet, allstruct* newlet)
    {
          strcpy(newlet->struct1->let.let1, "b");
          strcpy(newlet->struct1->let.let2, "c");
          strcpy(newlet->struct1->let.let3, "d");
    }
    
    void change(allstruct* structold, allstruct* structnew)
    {
          addnum(structold, structnew);
          pluslet(structold, structnew);
    }
    
    int main(void)
    {
            allstruct test;
            test.struct1 = malloc(sizeof *test.struct1); <--added
    
            test.struct1->num.num1 = 1;
            test.struct1->num.num2 = 2;
            test.struct1->num.num3 = 3;
            strcpy(test.struct1->let.let1, "a");
            strcpy(test.struct1->let.let2, "b");
            strcpy(test.struct1->let.let3, "c");
    
            printf("old num1: &#37;u\n", test.struct1->num.num1);
            printf("old num2: %u\n", test.struct1->num.num2);
            printf("old num3: %u\n", test.struct1->num.num3);
            printf("old let1: %s\n", test.struct1->let.let1);
            printf("old let2: %s\n", test.struct1->let.let2);
            printf("old let3: %s\n", test.struct1->let.let3);
    
            allstruct newtest;
            newtest.struct1 = malloc(sizeof *newtest.struct1); <--added
    
            change(&test, &newtest);
    
            printf("new num1: %u\n", newtest.struct1->num.num1);
            printf("new num2: %u\n", newtest.struct1->num.num2);
            printf("new num3: %u\n", newtest.struct1->num.num3);
            printf("new let1: %s\n", newtest.struct1->let.let1);
            printf("new let2: %s\n", newtest.struct1->let.let2);
            printf("new let3: %s\n", newtest.struct1->let.let3);
    
            free(test.struct1); <--added
            free(newtest.struct1); <--added
    
            return 0;
    }
    Now my problem is, when I compile the above code, everything is a-ok. (Also put -Wall flag on my compilation command just in case.) However, when I run the executable file, instead of printing the desired results on the screen, it produces a dump "core.xxxx" file. Now, I wouldn't just ask for help as long there something I can go by but thats just it, the compiler doesn't produce any warnings or errors. So now I'm stumped. I tried to search all over the web for a solution but I can't seem to find anything (most probably my google-fu is weak). So I ask if anyone can look over my code and point out what I did wrong. A clue would be fine also . Also feel free to criticize if you see anything bad in my work.

    Thanks for any and all response.
    Last edited by azerej; 05-22-2008 at 02:13 AM.

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    You can't pass by reference in C, everything is passed by value. However, you can pass a pointer to whatever it is you want to pass (which you're doing).

    Other than names, what's the difference from holder and holder2?

    > holder *struct1;
    Is a pointer to something (in this case, it's wild).
    You can't do anything to struct1 until you point it to something.

    ie,
    Code:
    holder * struct1;
    holder theData;
    
    struct1 = &theData;
    Other than that, it's fine, although you might want to work on meaningful varaible names. Also struct's are like blueprints, there's no need to define the same blueprints twice, (you can use the same blueprints to construct 2 different -- but identical in design, buildings).
    Last edited by zacs7; 05-22-2008 at 12:02 AM.

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Code:
    >typedef struct
    >{
    >        holder *struct1;
    >        holder2 *struct2;
    >} allstruct;
    To reiterate zacs's comments, these are just pointers. To actually store data, you must malloc() some storage for them:
    Code:
    test.struct1 = malloc(sizeof *test.struct1);
    test.struct2 = malloc(sizeof *test.struct2);
    Since you don't actually use struct2, you wouldn't actually need the second line, until you actually use struct2. A second solution would be to make struct1 and struct2 nonpointers:
    Code:
    typedef struct
    {
            holder struct1;
            holder2 struct2;
    } allstruct;
    Make sure to #include <stdlib.h> for malloc().
    Last edited by swoopy; 05-22-2008 at 12:28 AM.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Remember that all malloc must have a free later, otherwise you get a memory leak.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    May 2008
    Posts
    12
    Thank you!

    Quote Originally Posted by zacs7 View Post
    You can't pass by reference in C, everything is passed by value. However, you can pass a pointer to whatever it is you want to pass (which you're doing).

    Other than names, what's the difference from holder and holder2?

    > holder *struct1;
    Is a pointer to something (in this case, it's wild).
    You can't do anything to struct1 until you point it to something.
    Yes, a pointer. Sorry, got it confused. Thank you for pointing that out.

    Uhm, I guess I was just using it as a filler. I was recreating the source code I saw from memory. I specifically remembered that it was calling a structure that was passing two structures by pointers. So, I just copy and pasted. And there you have it two structures .

    Quote Originally Posted by zacs7 View Post
    Other than that, it's fine, although you might want to work on meaningful varaible names. Also struct's are like blueprints, there's no need to define the same blueprints twice, (you can use the same blueprints to construct 2 different -- but identical in design, buildings).
    Yeah, I know. I suck at naming things. Anyway, this is just an exercise so I wasn't at first really concerned anybody able to read it. I'll try to remember that though.

    Quote Originally Posted by swoopy
    To reiterate zacs's comments, these are just pointers. To actually store data, you must malloc() some storage for them:

    Code:
    test.struct1 = malloc(sizeof *test.struct1);
    test.struct2 = malloc(sizeof *test.struct2);
    Thank you for the code. I finally understood what I was lacking. Haven't really touched malloc() before so I had no idea what it was really about til now. Again thanks.

    Quote Originally Posted by Elysia
    Remember that all malloc must have a free later, otherwise you get a memory leak.
    Done and done. Off-topic: I'm a fan of yours .

    Again thank you everyone.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Passing structure by reference or pointer?
    By 7force in forum C Programming
    Replies: 8
    Last Post: 12-13-2010, 06:49 PM
  2. Using Vectors. MinGW warning
    By Viewer in forum C++ Programming
    Replies: 9
    Last Post: 03-26-2009, 03:15 PM
  3. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  4. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  5. Question about OpenGL/Linux
    By Ideswa in forum Linux Programming
    Replies: 12
    Last Post: 09-10-2006, 05:56 AM