Bonjour à vous tous !!.
Je suis actuellement en train de coder un mini gestionnaire de mémoire, dont je suis plutôt fier car il fonctionne parfaitement, enfin, presque^^.
Sous windows, le code fonctionne parfaitement bien, mais il me semble fonctionner différemment sous Ubuntu.
Je m'explique, lorsque mon gestionnaire ouvre le fichier de log, le premier appelle a l'opérateur surcharger delete[](void*), il est en fait appeler 2 fois, contre une fois pour les appels suivants. Cela est plutôt problèmatique, car ça me provoque un segfault. Je rappelle que ceci n'arrive pas sous Windows 7(enfin du moins chez moi^^).
Le plus bizarre, c'est que le code ne me provoque aucun segfault et est clean du côté de valgrind si le fichier n'est pas ouvert ^^.
On peut évidemment utiliser l"opérateur delete au lieu de delete[], mais après, ça ne fais pas super propre ^^.
Voilà donc le code ^^
main.cpp
memoire.h
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 #include "memoire.h" using namespace std; int main(void) { int *p = new int[50]; int *d = new int; double *c = new double[298]; double *pd = new double; delete p; delete pd; delete[] d; delete[] c; return 0; }
memoire.cpp
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 #ifndef MEMOIRE_H_INCLUDED #define MEMOIRE_H_INCLUDED #include <iostream> #include <cstdlib> #include <fstream> namespace qgm { class Memory { public : static Memory &instance(void); void *allocate(std::size_t, unsigned, char const*, bool); void desallocate(void*, bool); char const *getFileDelete(void); unsigned getLineDelete(void); void prepareDelete(unsigned, char const*); private : /* Constructeur et destructeur privé */ Memory(void); ~Memory(void); /* Block de mémoire */ struct TBlock { void *data; /* Pointeur alloué */ std::size_t size; /* Taille */ unsigned line; /* Ligne de l'allocation */ char const *file; /* Fichier de l'allocation */ bool array; /* L'objet allouer est ce un tableau ? */ TBlock *before; /* Block précedant */ TBlock *next; /* Block suivant */ }; struct TBlock_Control { std::size_t allocation; /* Nombre d'allocation */ TBlock *first; /* Premier block */ TBlock *last; /* Dernier block */ }; TBlock_Control m_Block; /** Fichier et ligne de la désallocation **/ char const *m_FDelete; unsigned m_LDelete; std::ofstream m_File;/* Fichier de sortie de l'allocation */ }; } inline void* operator new(std::size_t s, unsigned l, char const *f) { return qgm::Memory::instance().allocate(s, l, f, false); } inline void* operator new[](std::size_t s, unsigned l, char const *f) { return qgm::Memory::instance().allocate(s, l, f, true); } inline void operator delete(void *p) { qgm::Memory::instance().desallocate(p, false); } inline void operator delete[](void *p) { qgm::Memory::instance().desallocate(p, true); } inline void operator delete(void *p, unsigned l, char const *f) { qgm::Memory::instance().prepareDelete(l, f); qgm::Memory::instance().desallocate(p, false); } inline void operator delete[](void *p, unsigned l, char const *f) { qgm::Memory::instance().prepareDelete(l, f); qgm::Memory::instance().desallocate(p, true); } #define new new(__LINE__, __FILE__) #define delete qgm::Memory::instance().prepareDelete(__LINE__, __FILE__);\ delete #endif // MEMOIRE_H_INCLUDED
Merci de votre aide ^^
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189 #include "memoire.h" namespace qgm { Memory:: Memory(void) { m_Block.allocation = 0; m_Block.first = NULL; m_Block.last = NULL; m_File.open("Rapport/Fuites de memoires.txt"); } Memory:: ~Memory(void) { /* Si on a aucune allocation de faîtes */ if(m_Block.allocation == 0) m_File << "Aucune fuite de mémoire détecter."; /* Sinon on prévient le programmeur, et on libère la mémoire */ else { std::size_t t = 0; /* Taille totale non libérer */ TBlock *actu, *next; actu = m_Block.first; /* On libére les bloques un par un */ do { next = actu->next; t += actu->size; m_File << "Libération automatique du pointeur allouer de :\n" << actu->size << " octets dans le fichier : \n" << actu->file << '(' << actu->line << ')' << std::endl << std::endl; free(actu->data); free(actu); actu = next; }while(actu != NULL); /* On dit de combien d'octets les fuites auraient eu lieu^^ */ m_File << "Libération automatique de : " << t << " octets..."; } m_File.close(); } Memory &Memory:: instance(void) { static Memory inst; return inst; } void *Memory:: allocate(std::size_t s, unsigned l, char const *f, bool a) { /* On alloue p */ void *p = malloc(s); /* On alloue un nouveau block */ TBlock *block = (TBlock*)malloc(sizeof *block); /* Si une des allocations n'a pas fonctionner */ if(block == NULL || p == NULL) { m_File << "Impossible d'allouer " << s << " octets." << std::endl << f << '(' << l << ')' << std::endl; return NULL; } /* On le configure */ block->data = p; block->size = s; block->line = l; block->file = f; block->array = a; /* On vient de l'allouer, il n'y a pas de suivant */ block->next = NULL; /* Si la première allocation*/ if(m_Block.allocation == 0) { /*Le premier block est le dernier */ m_Block.first = block; block->before = NULL; } else { /* On configure l'ancien dernier block comme avant dernier */ m_Block.last->next = block; block->before = m_Block.last; } m_Block.allocation++; /* le dernier est donc celui la */ m_Block.last = block; /** On écrit dans notre fichier de log **/ m_File << "Allocation de " << s << " octets" << std::endl << f << '(' << l << ')' << std::endl << std::endl; return p; } void Memory:: prepareDelete(unsigned l, char const *f) { m_LDelete = l; m_FDelete = f; } void Memory:: desallocate(void *p, bool a) { TBlock *actu, *next, *before; /* On se place au premier block */ actu = m_Block.first; while(actu != m_Block.last && actu->data != p) actu = actu->next; if(actu->data != p) { /* Si le pointeur n'a pas été allouer avec l'allocateur */ m_File << "Mauvaise désallocation du pointeur " << p << " a la ligne " << m_LDelete << " du fichier : " << m_FDelete << std::endl; return; } /* On récupère les blocks précédant et suivant */ next = actu->next; before = actu->before; /* On fait rejoindre le block précédant avec le suivant Si c'est possible */ if(next != NULL) next->before = before; if(before != NULL) before->next = next; /* Si c'était le dernier block ou le premier block, On fait repointer les blocks de début et de fin */ if(actu == m_Block.first) m_Block.first = next; if(actu == m_Block.last) m_Block.last = before; m_Block.allocation--; /** On écrit dans notre fichier de log **/ m_File << "Désallocation du pointeur allouer d'une taille de :\n" << actu->size << " octets " <<"dans le fichier :\n" << actu->file << '(' << actu->line << ')' << "\nEst désallouer dans le fichier :\n" << m_FDelete << '(' << m_LDelete << ')' << std::endl; /* Si on c'est tromper de delete([]) */ if(actu->array != a) { m_File << "Attention tout de même :\n" "Ce pointeur n'a pas était désallouer " "avec la bonne version de 'delete'" << std::endl; } m_File << std::endl; /* On libère les pointeurs */ free(p); free(actu); } }
Partager