-2

I'm a total beginner to C (obviously), and I thought functions initA and initB were interchangeable, since they both return a pointer to an object of type List (a custom struct) but only initA produces the expected output.

How is initA different from initB ?

List *initA() {

    List *list = malloc(sizeof(*list));
    Element *element = malloc(sizeof(*element));

    element->number = 0;
    element->next = NULL;
    list->first = element;


    return list;
}


List *initB() {
    Element _el = {.number=0, .next=NULL};
    Element *el = &_el;
    List _list = {.first=el};
    List *list = &_list;
    return list;
}

Here is the full source code (trying to reproduce the first steps of a Linked List here, for pedagogic reasons)

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


typedef struct Element Element;
struct Element {
    int number;
    Element *next;
};


typedef struct List List;
struct List {
    Element *first;
};




List *initA() {

    List *list = malloc(sizeof(*list));
    Element *element = malloc(sizeof(*element));

    element->number = 0;
    element->next = NULL;
    list->first = element;


    return list;
}

List *initB() {
    Element _el = {.number=0, .next=NULL};
    Element *el = &_el;
    List _list = {.first=el};
    List *list = &_list;
    return list;
}




void printList(List *list){

    Element *el = list->first;
    while (NULL != el) {
        printf("number: %d, next: %p\n", el->number, el->next);
        el = el->next;
    }

}

int main(int argc, char *argv[]) {

    /**
     * output:  
     * number: 0, next: 0x0
     */
//    List *list = initA();

    /**
     * output:      
     * number: 1344951776, next: 0x7fff502a55d0
     * number: 1344951776, next: 0x29502a55e0
     */
    List *list = initB();
    printList(list);

    return 0;

}
ling
  • 9,545
  • 4
  • 52
  • 49
  • 2
    The difference is that `initB()` returns a pointer to a local variable which is *undefined behaviour*. There are *many* dups of this.. – P.P Jul 10 '15 at 14:24
  • Oh yes, now I start to understand Thank you. – ling Jul 10 '15 at 14:27

1 Answers1

0

initB returns a pointer to a locale variable, which has a scope limited to initB. Anything can happen to the memory located at this address when you exit that function. As such, this is undefined behavior

Eregrith
  • 4,263
  • 18
  • 39