Greetings !!

Je me suis retrouvé très con lorsqu'un de mes élèves m'a demandé pourquoi lorsqu'il utilisait return ça fonctionnait alors que en modifiant sa liste passée par adresse à la fonction ça ne fonctionnait pas.
Je "vois" plus ou moins mais j'ai du mal à formuler.

Voici la fonction qui "fonctionne" lol...

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
 
LinkedList* lc_sort(LinkedList *source,int (*fctcompare)(void*,void*))
{
	LinkedList	*tmpList=lc_init();
	lc_Datas		*tmpPG=NULL;
 
	int position=1;
 
	if(source==NULL) return NULL;
 
 
	lc_Datas		*compareme;
	lc_Datas		*parcours;
	do
	{
		parcours=source->pHead;
		if(parcours==NULL) break;																							
 
		compareme=lc_get(source,position);
 
		if(compareme==NULL) // cas du dernier élément non trié... automatiquement le plus petit
		{
			int ItemID=lc_add(parcours->value,tmpList,parcours->dataType,parcours->dataSize);
			lc_setDisplayByID(tmpList,ItemID,parcours->pDisplay);
			lc_delete(source,parcours->item_Number);
			break;
		}
		tmpPG=compareme;
 
		if(parcours->dataType!=compareme->dataType) break;																// on ne compare pas des pommes et des poires (ni C et Python)
		if(parcours->dataType==uepuserdef && fctcompare==NULL) break;										// si il n'y a pas de fonction de comparaison on quitte
 
		do
		{
 
			switch(parcours->dataType)
			{
				case uepbyte:			if(*((char*)parcours->value)>*((char*)tmpPG->value)) tmpPG=parcours;
													break;
				case uepshort:    if(*((short*)parcours->value)>*((short*)tmpPG->value)) tmpPG=parcours;
													break;
				case uepint:			if(*((int*)parcours->value)>*((int*)tmpPG->value)) tmpPG=parcours;
													break;
				case uepfloat:		if(*((float*)parcours->value)>*((float*)tmpPG->value)) tmpPG=parcours;
													break;
				case ueplong:			if(*((long*)parcours->value)>*((long*)tmpPG->value)) tmpPG=parcours;
													break;
				case uepllong:	  if(*((long long*)parcours->value)>*((long long*)tmpPG->value)) tmpPG=parcours;
													break;
				case uepdouble:		if(*((double*)parcours->value)>*((double*)tmpPG->value)) tmpPG=parcours;
													break;
				case uepldouble:	if(*((long double*)parcours->value)>*((long double*)tmpPG->value)) tmpPG=parcours;
													break;	
				default:					if(fctcompare(parcours->value,tmpPG->value)>0) tmpPG=parcours;
			}
			parcours=parcours->pNext;
		}while(parcours!=NULL);
		// Ici nous avons l'élément le plus grand de la collection de valeurs...
		lc_Datas *copy=lc_search(source,tmpPG->item_Number);
		int ItemID=lc_add(copy->value,tmpList,tmpPG->dataType,tmpPG->dataSize);
		lc_setDisplayByID(tmpList,ItemID,compareme->pDisplay);
		lc_delete(source,tmpPG->item_Number);
		tmpPG=NULL;
	}while(source->NbElem>0);
	// La liste devrait être triée
	return tmpList;
}
Ici on obtient une liste chaînée contenant "quelque chose" qu'il faut trier.
Cette manière de procéder permet dans le code source de faire quelque chose comme ceci:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
printf("Entiers: \n");
lc_showList(ll_datas_int);
ll_datas_int=lc_sort(ll_datas_int,NULL);
printf("Entiers triés: \n");
lc_showList(ll_datas_int);
...et d'obtenir ceci:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
Entiers: 
35
66
38
24
85
Entiers triés: 
85
66
38
35
24
...ce qui est magnifique !!

Maintenant, au départ l'étudiant -- avait fait ceci:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
void lc_sort(LinkedList *source,int (*fctcompare)(void*,void*))
{
  LinkedList	*tmpList=lc_init();
...
et tout à la fin avant la fin de la fonction
  source=tmpList;
}
...là par contre ça ne fonctionnait pas...

Je dois bien dire que -- pour moi -- ça devrait fonctionner, source est un pointeur vers une structure de type LinkedList et tmpList pointe sur une structure de type LinkedList.
Le passage par adresse, pour moi, permet de modifier le contenu de l'argument (ou paramètre) passé à la fonction... or ici manifestement ce n'est pas le cas, au retour de la fonction, ll_datas_int contient bien une adresse mais
tout le reste de la structure est NULL... du coup je sais pas trop bien expliquer.

Ici source est placé sur la pile donc je supposes que l'adresse est codée sur 64bits, tout comme tmpList on aurait tendance de le dire, mais, lui, il provient du heap... lc_init() cache un calloc() ... je pense que le soucis vient de là.
Lorsque nous faisons return nous "dépilons" donc il devrait y avoir un alignement par rapport aux données pointées par les pointeurs respectifs.

J'ai vraiment du mal à être clair sur ce sujet et je ne parviens pas à expliquer pourquoi, ici, les pointeurs n'ont pas l'air de fonctionner et semblent ne pas permettre de se défaire, notamment, de la "limitation liée aux variables locales aux fonctions".