Reputation: 132
i dont know why the list returned is NULL
, this is the code:
In my List.h
struct nodo_ {
char* dato;
struct nodo_ *next;
};
struct nodo_ *Lista;
/*Def list */
void createList(struct nodo_ **Lista);
in my main.c
struct nodo_ *Lista;
int main(){
createList(Lista);
while(Lista != NULL){
printf("The date is %s\n ",Lista->dato); //Error here now
Lisa = Lista->next;
}
return 0 ;
}
in my List.c im create the List :
void createList(struct nodo_ *Lista){
struct nodo_ *Aux_List = list_D;
aux_List = malloc(sizeof(struct nodo_));
char* path_a = "Hello";
char* path_B = "Minasan";
/* Store */
aux_List->dato = path_a;
aux_List = Aux_List->next;
aux_List = malloc(sizeof(struct nodo_));
aux_List->dato = path_b;
aux_List->next = NULL;
}
Thanks.
Upvotes: 0
Views: 2767
Reputation: 67852
Short answer to your actual question before I dig into the code:
... why the list returned is NULL ...
There is no returned list, you neither use return
to pass a result, nor set the value of an out parameter.
In your edited code:
void createList(struct nodo_ **Lista){
struct nodo_ *Aux_List = list_D;
aux_List = malloc(sizeof(struct nodo_));
you first set Aux_List
to the current value of Lista
, which you know isn't initialized yet, because you're trying to initialize it. Then you discard that value, overwriting aux_List
with a new address returned by malloc
. You never store anything into *Lista
, which would be the only way for this function to work as declared.
As Ed suggests, your typedef is hiding lots of useful information from you, so let's expand it out
struct nodo {
char* dato;
struct nodo *next;
};
/*Def list */
void createList(struct nodo* list_D);
Now, you can see this createList
is wrong: you can pass in the head node of a list (which is no use to it anyway), but there is no way for it to return a newly-allocated list to the caller.
Frankly your createList
isn't a useful primitive anyway, so I'm going to start with a sensible foundation first:
struct nodo *alloc_nodo(char *dato, struct nodo *next)
{
struct nodo *n = malloc(sizeof(*n));
n->dato = dato;
n->next = next;
return n;
}
Now, before we re-write your createList
using this, let's see what it does now:
void createList(struct nodo *list_D)
{
struct nodo *aux_List = list_D;
aux_List = malloc(sizeof(struct nodo_));
/* ^ so, we take the input argument and immediately discard it */
char* path_a = "Hello";
char* path_B = "Minasan";
/* Store */
aux_List->dato = path_a;
aux_List = Aux_List->next;
/* ^ note that we haven't initialized aux_List->next yet,
so this is a random pointer value */
aux_List = malloc(sizeof(struct nodo_));
/* again, we set aux_List to something,
but immediately overwrite and discard it */
aux_List->dato = path_b;
aux_List->next = NULL;
}
So, it ignores its input, returns no output, and leaks two partially-initialized nodes which aren't connected to each other. I believe you wanted to achieve something more like this:
struct nodo* create_my_list()
{
struct nodo *tail = alloc_nodo("Minasan", NULL);
/* the end (tail) of the linked list has a NULL next pointer */
struct nodo *head = alloc_nodo("Hello", tail);
/* the head of the linked list points to the next node */
return head;
/* like a snake, you hold a singly-linked list by the head */
}
If we write main
to use this function now, it looks like:
int main()
{
struct nodo *head = create_my_list();
struct nodo *n;
for (n = head; n != NULL; n = n->next)
{
printf("The date is %s\n ", n->dato);
}
}
Upvotes: 1
Reputation: 124790
That pointer is being passed by value, i.e., a copy is made. If you wish to initialize the pointer to a completely new value then you must use another level of indirection (i.e., a nodo_**
).
On a side note, typedef
ing pointer types is almost always a bad idea unless the type is truly opaque (which yours is not). One reason for this "rule" is evident when you consider another bug in your code:
auxList = (Lista*)malloc(sizeof(Lista));
You're allocating space for a pointer to noda_
, not enough for a noda_
object. Also, don't cast the return value of malloc
in C. It is redundant as a void*
is safely and implicitly converted to any other pointer type and, if you forget to include stdlib.h
, malloc
will be assumed to be a function which returns int
, and the cast hides the error. (only applies to compilers which implement C89 or an older version)
EDIT:
To initialize a pointer argument within a function:
void init(struct node **n) {
if(n)
*n = malloc(sizeof(struct node));
}
int main() {
struct node *n;
init(&n);
}
Upvotes: 3