Bonjour, une erreur s'est glissée dans mon code, saurez vous la retrouver.
En fait, je cherche à gérer un tableau de structures de façon dynamique (malloc). Chaque structure représente les informations d'une connexion FTP. Mon code plante lorsque je souhaite ajouter une deuxième structure, la première insertion se déroule sans soucis.
Ci après le code incriminé :
Le problème se situe à la sortie de la fonction resize_connexion() qui est censée modifier la taille du tableau. Quand on est dans la fonction, le tableau a bien la taille désirée, cependant, une fois ressorti on retrouve l'ancienne taille.
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
68
69 struct connexionftp *resize_connexion(struct connexionftp *p_conn, int *curr_size, int new_size) { if (p_conn == NULL) return p_conn; if (curr_size == NULL) return p_conn; if (new_size < 0) return p_conn; if (new_size == 0) { p_conn = free_connexion(p_conn); if (p_conn == NULL) { *curr_size = 0; return NULL; } return p_conn; } p_conn = (struct connexionftp *) realloc(p_conn, new_size * sizeof(struct connexionftp)); if (p_conn == NULL) { *curr_size = 0; return NULL; } *curr_size = new_size; return p_conn; } void copy_connexion(struct connexionftp **p_dest, const struct connexionftp * const p_src, const int index) { strcpy(p_dest[index]->host, p_src->host); strcpy(p_dest[index]->username, p_src->password); strcpy(p_dest[index]->password, p_src->password); p_dest[index]->port = p_src->port; } short add_connexion(struct connexionftp **p_list, int *size, struct connexionftp *p_ftp) { if (p_ftp == NULL) return false; if (p_list == NULL) return false; if (size == NULL) return false; if (*p_list == NULL) { *p_list = get_connexion(1); if (*p_list == NULL) return false; *size = 1; } else { /** Partie qui pose problème **/ *p_list = resize_connexion(*p_list, size, *size + 1); if (*p_list == NULL) return false; } copy_connexion(p_list, p_ftp, *size - 1); return true; }
Une exécution du programme à l'aide de GDB pourra vous aider à comprendre :
On peut dire que la fonction add_connexion() est appelée de cette façon :
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 (gdb) r Starting program: main Que voulez-vous faire ? [C] Consulter la liste [A] Ajouter une connexion [M] Modifier une connexion [S] Supprimer une connexion [E] Enregistrer [Q] Quitter > a Ajout d'une connexion Hôte : fg Nom d'utilisateur : fg Mot de passe : fg Port : 21 Breakpoint 2, add_connexion (p_list=0xbffff6e8, size=0xbffff6e4, p_ftp=0x804b008) at ftp.c:76 76 copy_connexion(p_list, p_ftp, *size - 1); (gdb) c Continuing. Que voulez-vous faire ? [C] Consulter la liste [A] Ajouter une connexion [M] Modifier une connexion [S] Supprimer une connexion [E] Enregistrer [Q] Quitter > a Ajout d'une connexion Hôte : fg Nom d'utilisateur : fg Mot de passe : fg Port : 21 Breakpoint 1, add_connexion (p_list=0xbffff6e8, size=0xbffff6e4, p_ftp=0x804b008) at ftp.c:73 73 *p_list = resize_connexion(*p_list, size, *size + 1); (gdb) p *p_list $1 = (struct connexionftp *) 0x804b310 (gdb) p *p_list[0] $3 = {host = "fg", '\000' <repeats 252 times>, username = "fg", '\000' <repeats 252 times>, password = "fg", '\000' <repeats 252 times>, port = 21} (gdb) s resize_connexion (p_conn=0x804b310, curr_size=0xbffff6e4, new_size=2) at mem.c:28 28 if (p_conn == NULL) return p_conn; (gdb) s 29 if (curr_size == NULL) return p_conn; (gdb) s 32 if (new_size < 0) return p_conn; (gdb) s 33 if (new_size == 0) (gdb) s 46 p_conn = (struct connexionftp *) realloc(p_conn, new_size * sizeof(struct connexionftp)); (gdb) s 47 if (p_conn == NULL) (gdb) p p_conn $4 = (struct connexionftp *) 0x804b310 (gdb) p p_conn[0] $5 = {host = "fg", '\000' <repeats 252 times>, username = "fg", '\000' <repeats 252 times>, password = "fg", '\000' <repeats 252 times>, port = 21} (gdb) p p_conn[1] $6 = {host = "\361\t\002", '\000' <repeats 251 times>, username = '\000' <repeats 254 times>, password = '\000' <repeats 254 times>, port = 0} (gdb) s 54 *curr_size = new_size; (gdb) s 57 return p_conn; (gdb) p *curr_size $7 = 2 (gdb) c Continuing. Breakpoint 2, add_connexion (p_list=0xbffff6e8, size=0xbffff6e4, p_ftp=0x804b008) at ftp.c:76 76 copy_connexion(p_list, p_ftp, *size - 1); (gdb) p *p_list $8 = (struct connexionftp *) 0x804b310 (gdb) p *p_list[0] $9 = {host = "fg", '\000' <repeats 252 times>, username = "fg", '\000' <repeats 252 times>, password = "fg", '\000' <repeats 252 times>, port = 21} (gdb) p *p_list[1] Cannot access memory at address 0x3 (gdb) p *size $10 = 2 (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0xb7ee6884 in strcpy () from /lib/libc.so.6 (gdb)
Celle-ci est censée copier les champs de p_conn dans une nouvelle case de p_list.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 struct connexionftp *p_list = NULL; struct connexionftp *p_conn = NULL; int size = 0; p_conn = new_connexion(); add_connexion(&p_list, &size, p_conn); p_conn = free_connexion(p_conn);
La fonction new_connexion() demande juste à l'utilisateur de saisir les infos et retourne une pointeur sur la structure connexionftp.
Je n'arrive pas à trouver à quoi cela peut-être dû...![]()
Partager