Bonjour,

Je fais face aux joies du c++ avec des problèmes que je considère comme des "effets de bord". En effet une variable change de valeur sans raison. Je fais donc du débogage pas à pas avec gdb, en suivant la valeur d'une de mes variables "FILE* file" (Je sais que je devrais utiliser fstream en c++, mais j'obtiens le même problème, j'ai donc utilisé FILE* pour le mettre en évidence). En déboguant avec gdb, j'obtiens:
- initialisation de file dans le constructeur d'une classe Replay:
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
Breakpoint 1, Replay::Replay (this=0x7ffffffed9d8, pixels_per_unit=32, width=24, height=24)
    at ../SimplePvP/Replay.cpp:38
38      Replay::Replay(int pixels_per_unit, float width, float height)
(gdb) next
40              file = fopen("0.replay", "wb");
(gdb) next
42              WriteUint16(pixels_per_unit);
(gdb) p file
$16 = (FILE *) 0x84d2c20
(gdb) p &file
$17 = (FILE **) 0x7ffffffed9e0
(gdb) p *(FILE**)0x7ffffffed9e0
$18 = (FILE *) 0x84d2c20
(gdb) next
43              WriteFloat32(width);
(gdb) next
44              WriteFloat32(height);
(gdb) next
45      }
- bazar dans la classe de base dont file est l'attribut:
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
(gdb) next
GameManager::GameManager (this=0x7ffffffed9c0, nb_players_=3, pixels_per_unit=32, width=24, height=24)
    at ../SimplePvP/GameManager.cpp:10
10              unsigned int seed = time(NULL);
(gdb) next
11              srand(seed);
(gdb) next
12              std::cout << "Seed: " << seed << std::endl;
(gdb) next
Seed: 1567342599
13              turn = -1;
(gdb) next
14              current_player = -1;
(gdb) p *(FILE**)0x7ffffffed9e0
$19 = (FILE *) 0x84d2c20
(gdb) next
15              scores = new int[nb_players];
(gdb) next
16              for (int playerId = 0; playerId < nb_players; playerId++)
(gdb) next
17                      scores[playerId] = 1;
(gdb) next
16              for (int playerId = 0; playerId < nb_players; playerId++)
(gdb) next
17                      scores[playerId] = 1;
(gdb) next
16              for (int playerId = 0; playerId < nb_players; playerId++)
(gdb) next
17                      scores[playerId] = 1;
(gdb) next
16              for (int playerId = 0; playerId < nb_players; playerId++)
(gdb) next
18      }
(gdb) p *(FILE**)0x7ffffffed9e0
$20 = (FILE *) 0x84d2c20
- et dès que je quitte le constructeur de la classe de base (GameManager) pour revenir dans le constructeur de la classe fille qui l'avait appelée (SimplePvPGameManager), le pointeur change par magie:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
(gdb) next
SimplePvPGameManager::SimplePvPGameManager (this=0x7ffffffed9c0) at ../SimplePvP/SimplePvPGameManager.cpp:27
27              for (int i = 0; i < NB_WALLS; i++) {
(gdb) p *(FILE**)0x7ffffffed9e0
$21 = (FILE *) 0x60000000a

Sachant que ces trois parties s'enchaînent, et qu'il ne s'est donc rien passé entre, auriez-vous une idée d'où peut venir un tel problème? (Vous me redonneriez la foi dans le c++ si vous dites que c'est ma faute, mais pour le moment, c'est mieux le c# )

Merci d'avance pour votre expertise!


EDIT: Je mis ici en annexe le code correspondant au débogage, si vous souhaitez avoir une vue d'ensemble:
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
Replay::Replay(int pixels_per_unit, float width, float height)
{
	file = fopen("0.replay", "wb");
	//file.open("0.replay", ios::binary | ios::out);
	WriteUint16(pixels_per_unit);
	WriteFloat32(width);
	WriteFloat32(height);
}
 
GameManager::GameManager(int nb_players_, int pixels_per_unit, float width, float height) : 
	nb_players(nb_players_),
	replay(pixels_per_unit, width, height)
{
	unsigned int seed = time(NULL);
	srand(seed);
	std::cout << "Seed: " << seed << std::endl;
	turn = -1;
	current_player = -1;
	scores = new int[nb_players];
	for (int playerId = 0; playerId < nb_players; playerId++)
		scores[playerId] = 1;
}
 
SimplePvPGameManager::SimplePvPGameManager() : GameManager(NB_PLAYERS, 32, SIZE_MAP, SIZE_MAP)
{
    ...
}
(Dommage qu'il n'y ait pas la possibilité de créer de spoiler pour cacher les choses facultatives, et ainsi moins encombrer les posts...)