Thread: An empty function, taking 2 structs as arguments, overwrites one with the other

  1. #1
    Registered User
    Join Date
    Sep 2016
    Posts
    2

    An empty function, taking 2 structs as arguments, overwrites one with the other

    Hello all,

    I've come across a strange bug in my code while attempting to make a simple singly linked list. I first noticed the bug while attempting to append multiple items to the list and then print their contents, which caused an infinite loop. After some digging, I discovered that the cause seemed to be a problem with my pointers, and I was eventually able to pare it down until I worked out the exact spot that was causing me trouble. The problem is, I don't know why it's causing issues. Here is the code, cut down as much as I could get it and still reproduce the bug:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    struct SingleNode {
        int data;
        struct SingleNode *next;
    };
    
    
    struct SingleList {
        struct SingleNode *head;
    };
    
    
    struct SingleNode newSingleNode(int data)
    {
        struct SingleNode new;
        new.data = data;
        new.next = NULL;
        return new;
    }
    
    
    struct SingleList newSingleList()
    {
        struct SingleList new;
        new.head = NULL;
        return new;
    }
    
    
    void nodeGlitch(struct SingleList *s, struct SingleNode n)
    {
    }
    
    
    void appendNode(struct SingleList *s, struct SingleNode n)
    {
        if (s->head == NULL)
        {
            s->head = &n;
        }
    }
    
    
    int main()
    {
        struct SingleList list = newSingleList();
        struct SingleNode a = newSingleNode(3);
        struct SingleNode b = newSingleNode(5);
        appendNode(&list, a);
        printf("Head is %i\n", list.head->data);
        nodeGlitch(&alpha, b);
        printf("Head is %i\n", list.head->data);
        printf("a is %i\n", list.head);
        return 0;
    }
    This program produces the following output:
    Code:
    Head is 3
    Head is 5
    a is 3
    a is unchanged, but the head of list now has "5" in its data field - in other words, it now points to b. This happens even though the only thing that changed between the two printf() calls was a call to the empty function nodeGlitch(). I assume it must have something to do with the arguments passed into nodeGlitch(), but I don't see why an empty function would overwrite a pointer in its first argument with the address of its second. Anyone know why this would happen, and how I can avoid it passing structs to functions in the future?
    Last edited by StarmanGhost; 09-20-2016 at 05:57 PM. Reason: Fixed formatting

  2. #2
    Registered User camel-man's Avatar
    Join Date
    Jan 2011
    Location
    Under the moon
    Posts
    693
    You are actually only passing a copy of singleNode into your append function. This means that when the function returns/ends the parameter will disappear. If you want to pass by reference I suggest making the parameter of type struct SingleNode* in your append function. Then in your body you would assign like the following : s->head = n; //instead of ampersand

    example:
    Code:
    void appendNode(struct SingleList *s, struct SingleNode* n){    if (s->head == NULL)    {        s->head = n;    }}
    
    //main 
    
    appendNode(&list, &a);
    Looks like your code is displaying undefined behavior. Once your appendNode function ends, the parameter struct SingleNode n goes away thus s->head is still pointing to some invalid address or null. Depends... after that you should not be trying to print from head values. This is where the UB(undefined behavior) is being displayed. You should also note in the last printf, that %I is for printing integers, if you want to print the address of a variable, use %p. That is another example of UB.
    Last edited by camel-man; 09-20-2016 at 06:40 PM.
    Code:
    int get_random_number(void)
    {
       return 4; //chosen by fair dice roll.
                 //guaranteed to be random
    }

  3. #3
    Registered User
    Join Date
    Sep 2016
    Posts
    2
    Thanks for the quick response! I tried the code with the changes you suggested, and it works as intended now

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 05-25-2015, 02:45 PM
  2. Replies: 8
    Last Post: 08-24-2011, 10:26 AM
  3. Replies: 1
    Last Post: 06-14-2010, 01:26 PM
  4. Replies: 9
    Last Post: 10-20-2008, 10:23 AM
  5. Replies: 4
    Last Post: 01-17-2006, 12:43 PM

Tags for this Thread