pointer to structure passed by ref

Discussion in 'C Programming' started by Excluded_Middle, Jun 24, 2003.

  1. consider the following code

    /***********************************************************************/
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    struct student {
    int id;
    char name [100];
    struct student * next;
    };

    void printStudents(struct student *p) {
    printf("Printing the list of students \n");
    for (p; p != NULL; p=p->next)
    printf ("id=%d name=%s \n",p->id,p->name);

    printf("\n");
    }

    int main () {
    struct student *p, *head, *mid, *tail;

    p=(struct student *) malloc (sizeof(struct student));
    p->id=12; strcpy(p->name,"Tom"); p->next=NULL; head=p;
    tail=p;

    p=(struct student *) malloc (sizeof(struct student));
    p->id=7; strcpy(p->name,"Bob"); p->next=NULL; tail->
    next=p; tail=p; mid=p;

    p=(struct student *) malloc (sizeof(struct student));
    p->id=9; strcpy(p->name,"Rob"); p->next=NULL;
    tail-> next=p; tail=p;

    printStudents(head);

    printStudents(head);

    return 0;
    }
    /****************************************************************************/

    My question is head is a pointer to student struct and is passed by
    ref to function printStudents when I call this function for the second
    time it give me same result why?

    Is there any that I can change head in printStudent and that change
    also effects in main function.

    thank you.
     
    Excluded_Middle, Jun 24, 2003
    #1
    1. Advertisements

  2. Because the function printStudents() can only modify its local copy of
    the parameter "p". You are not passing by reference, you're passing a
    pointer by address. Just because you're passing a pointer does not
    magically mean passing by value means passing by reference.
    Pass the *address* of head and make printStudent() accept a
    struct student ** instead of a struct student *.

    You would also want to see the comp.lang.c FAQ. This question has been
    asked here thousands of times. The fact that pointers are passed by
    value just like anything else might seem confusing at first - after all,
    pointers are used to fake passing by reference - but it is logical when
    you come to think about it.

    --
    /-- Joona Palaste () ---------------------------\
    | Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
    | http://www.helsinki.fi/~palaste W++ B OP+ |
    \----------------------------------------- Finland rules! ------------/
    "This is a personnel commuter."
    - Train driver in Scientific American
     
    Joona I Palaste, Jun 24, 2003
    #2
    1. Advertisements

  3. Thanx for your answer. I am afraid that I have not much time to take
    look at comp.c faq. one more quicke question. I have a function.

    /***************************************************************************
    Implement this function so that your data structures are cleaned
    and associated memory freed up.

    */
    #include "ern_expression.h"

    void finalize (exp_ptr head, exp_ptr tail) {
    #ifdef TRACE
    printf ("TRACE: in function finalize \n");
    #endif


    }
    /****************************************************************/

    here exp_ptr is
    typedef struct ern_exp * exp_ptr;

    typedef struct ern_exp {
    char token[MAXLENGTH] /*MAXLENGTH = 30*/
    int value;
    exp_ptr next;
    }ern_node;

    which defined in the header file that is included above

    I have to pass the head and tail so that I clean up the memory using
    free(p);
    is there anywhay that I can't change the param and do that action.
     
    Excluded_Middle, Jun 24, 2003
    #3
  4. I'm afraid I don't understand your question. I'll make do with a best
    guess.
    If you are asking how you can free your list without being able to
    change the variable in the original function (for example main()), the
    answer is that you don't *need* to change the variable in the original
    function. Just use free() in a loop freeing each node until you reach
    the tail. The memory will still be freed. The original variable will
    be left pointing to non-allocated memory, but if you don't use that
    variable, all will be fine.

    --
    /-- Joona Palaste () ---------------------------\
    | Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
    | http://www.helsinki.fi/~palaste W++ B OP+ |
    \----------------------------------------- Finland rules! ------------/
    "You could take his life and..."
    - Mirja Tolsa
     
    Joona I Palaste, Jun 24, 2003
    #4
  5. Ok thank you for reply.

    You mean that the values from head to tail still exist but they are
    freed. If yes then how should I trace memory leaks in my program.
     
    Excluded_Middle, Jun 24, 2003
    #5
  6. (Excluded_Middle) wrote (24 Jun 2003) in
    / comp.lang.c:

    If the following is not responsive to your question, could you explain
    better what you want? Note the new function 'modify'. BTW, call-by-
    reference has no meaning in C; all parameters are passed by value.

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

    struct student
    {
    int id;
    char name[100];
    struct student *next;
    };

    void printStudents(struct student *p)
    {
    printf("Printing the list of students \n");
    for (; p; p = p->next)
    printf("id=%d name=%s \n", p->id, p->name);
    printf("\n");
    }

    void modify(struct student *p, int id, char *name)
    {
    p->id = id;
    strcpy(p->name, name);
    }

    int main()
    {
    struct student *p, *head, *mid, *tail;

    p = malloc(sizeof *p);
    if (p)
    *p = (struct student) {
    .id = 12,.name = "Tom",.next = NULL};
    else {
    fprintf(stderr, "malloc failure\n");
    exit(EXIT_FAILURE);
    }
    head = p;
    tail = p;

    p = malloc(sizeof *p);
    if (p)
    *p = (struct student) {
    .id = 7,.name = "Bob",.next = NULL};
    else {
    fprintf(stderr, "malloc failure\n");
    exit(EXIT_FAILURE);
    }
    tail->next = p;
    tail = p;
    mid = p;

    p = malloc(sizeof *p);
    if (p)
    *p = (struct student) {
    .id = 9,.name = "Rob",.next = NULL};
    else {
    fprintf(stderr, "malloc failure\n");
    exit(EXIT_FAILURE);
    }
    tail->next = p;
    tail = p;

    printStudents(head);
    modify(head, 17, "Becky");
    printStudents(head);
    for (p = head; p; p = tail) {
    tail = p->next;
    free(p);
    }

    return 0;
    }
     
    Martin Ambuhl, Jun 25, 2003
    #6
  7. (Excluded_Middle) wrote (24 Jun 2003) in
    / comp.lang.c:
    If you don't have time to check the FAQ, we don't have the time to bother
    with you.

    *plonk*
     
    Martin Ambuhl, Jun 25, 2003
    #7
  8. To properly trace memory leaks you need a debugger, which is outside the
    scope of comp.lang.c. Within the C language itself you will have to do
    with checking that each malloc() call is matched with a free() call.

    --
    /-- Joona Palaste () ---------------------------\
    | Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
    | http://www.helsinki.fi/~palaste W++ B OP+ |
    \----------------------------------------- Finland rules! ------------/
    "You will be given the plague."
    - Montgomery Burns
     
    Joona I Palaste, Jun 25, 2003
    #8
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.